September 30, 2004

Let's go one step farther...

I noticed on .NET Undocumented that Microsoft is currently accepting votes as to how important it is to have updated icons distributed with Visual Studio 2005. (You will need a Passport to vote, and you may have to fill out some minor registration details.)

Personally, I think that Microsoft should go one step farther. Any icon released with any of their application programs should be released with an icon for unrestricted free use on Windows platforms.

Why? Microsoft hired artists and paid them a pretty penny to make those icons easy to use and understandable? Why would Microsoft release those icons for free use? Easy. Microsoft has a vested interest in it. Microsoft is always pushing the Windows User Experience. They've even got the Official Guidelines online for anyone to read. While not as strict as Apple's UI Guidelines, Microsoft's are very straightforward, and stress the uniformity of the Windows User Experience.

The entire concept behind Windows is that your programs look and function in a similar fashion. With Visual Studio 2005, Microsoft is providing developers with UI controls that finally look and function like the controls in Office 2003.

Microsoft invests millions of dollars every year in usability research. These icons and controls are the result of that research. In order for that research to advance the Windows platform, Microsoft has essentially two choices here.

One: Microsoft can maintain the status quo. Microsoft can leave the UI resources included with Visual Studio at the same level that it has been since Visual Basic 1.0...Windows 3.0 icons and graphics. This works well for third party developers like Infragistics. They can sell overpriced controls that look and feel like Microsoft's controls. Those who cannot afford these controls are forced to look for open source controls or spend a massive amount of time reinventing the wheel.

Two: Microsoft can release their UI components or act-alikes with Visual Studio. The average appearance of Windows software from 3rd parties will improve dramatically (or legally, in the cases where people have jacked the UI components without permission). Infragistics and friends will have to actually work on dramatically new components.

Now, I'm not talking about display components, like charting components. Those are a definite value-add to the product that they come in. I'm talking about the basic UI components: buttons, menus, menubars, scrollbars, the icon glyphs that accompany certain tasks, those sorts of things.

Microsoft, if you give us the tools we need to make Windows more attractive with a low cost, we can make it harder to look at Linux as an alternative. Don't make us reinvent the wheel to keep up, and we'll spend that extra effort pushing the Windows platform ahead.

September 29, 2004

GAG: The Newsletter, The Dream, The Reality

Back when I was working the arcade in the Ogden City Mall, I started writing a small newsletter for our regular customers. It was called "GAG: The Gamers Advocacy Group." It was just a single sheet photocopied at my own expense that I would give to our regulars. It would have tips on new moves for the games, reviews of games from other arcades, and information on upcoming games.

I kept writing the newsletter for the next several years, transitioning it to an E-mail list in 1994. It varied between daily and weekly, depending on how much news I could dig up. I'd always include my own smart-ass reviews and take on the news as well. At its peak, my subscriber list was in the mid-500's, which wasn't too bad. A good two-thirds of my subscribers were developers, testers, etc., who enjoyed feeding me information.

When I joined Access Software, I was told that I could continue to do GAG under two conditions. First, I was not allowed to talk about any Access Software product in the newsletter. Second, I was not allowed to mention that I worked for Access Software. They did that as a precautionary measure. They didn't want anything I said to come back to them. In addition to keeping the promise, I also added the standard "opinions are my own, not necessarily that of my employer" clause to the bottom of my messages.

When Microsoft acquired Access, I had to put GAG on hold while Microsoft Legal reviewed my agreement. Imagine my surprise when they said I could continue to do GAG as long as I didn't tell people I worked for Microsoft. They actually removed one of the restrictions on me. I still didn't cover titles from my studio, but everything else in Microsoft was fair game.

GAG was fun, and I kept doing it to keep my sanity. However, the workload at Microsoft is heinous. Going from daily to weekly to monthly was a horrible experience. I put GAG on hiatus in late 2001, and when I lost the subscriber list in early 2002 due to a hard drive crash, most of my motivation to continue GAG went away.

It's a shame, too. If I had been able to keep the time to do it, I might not have burned out as bad at Microsoft as I had.

Charity for Florida

Just a reminder: if you're going to donate to the rebuilding of Florida, remember to donate to an established charitable organization. They have the infrastructure in place and the connections to ensure that your money gets put to the best possible use.

I donate to The United Way. I can't donate much...after all, I took a 33% pay cut when I left Microsoft. But I donate what I can.

September 28, 2004

Links LS 1999 Edition: Links, the Access way

I was thrown in feet first working on Links LS 1999 Edition. This was the first iteration of Links to allow St. Andrew's-style pit bunkers, as well as the first iteration to support 3D objects. I was brought in near the tail-end of the development cycle, so the development team was really starting to crack down on bug submissions.

Let me see how I can best sum up the Access way of doing things: ship it and patch it until it was right. Access had their cost structure set up in such a way that support calls weren't the death knell that they are to the rest of the industry. They also had a bit of a secret margin on every unit (more on that later).

As a result of the Access way, testing was pretty much an afterthought. The test plan was to throw the test department and the tech support staff at the game until it broke, fix it, and repeat. The test department received the manual for a tech review three days after it went to press. Needless to say, it was an interesting experience.

There were a few things that surprised me, however. Very few people worked on Sundays. Admittedly, this is a very religious state, but in other local game companies, Sunday was just another day. The only real pressure in the office was pressure that you placed on yourself to do great work. I remember Les Oswald re-editing video clips of the courses over and over again because they just didn't feel right to him.

My most vivid memory of that product was the first bug I had to fight for. Near the first tee box on St. Andrews Old Course is a little shack. Due to a bug in the 3D model, you could see through the undersides of the shack roof. (The normals were facing wrong on the polygons.) It basically looked like total ass. I bugged it, and it came back "Won't Fix." It took me nearly two weeks of arguing up the chain of command to get it fixed. The fix took less than 20 minutes to find and fix. This series of events is one that becomes all-too-common for a tester.

So, what was the secret margin on each box of Links LS 1999 Edition? Would you believe that it was the box itself? Of course you wouldn't. That's why it was a secret.

Near the end of his service at Microsoft, he may have become a raging egomaniac because of PC Gamer calling him a "Game God," but you can say one thing for Bruce Carver...he was a hell of a negotiator. Due to his price negotiation skills, the price for the box was about one-fifth the price that other companies paid for their boxes. On Microsoft Golf 2001 Edition, a plain, non-embossed box with a paper sleeve to hold the disk and no manual had a total materials cost of goods of nearly $10, whereas the LS99 packaging, with multiple CD's, Arnold Palmer embossed on the package, a real jewel case, a full manual, etc., and a flap on the box was sub-$5.

In an industry where every dollar extra on a franchise can amount to boucoup bucks, Bruce's packaging helped ensure a steady revenue source...especially since the packaging for the courses was even cheaper.

He bought the disk cases in bulk from cheap manufacturers. He bought the boxes from local companies that wanted the recurring business and were willing to offer discounts for repeat customers. His shipping and packaging staff was a skeleton crew. He only cello-wrapped the course boxes, not the main game. He took care of the disk replication locally. Finally, in order to get the game packed and shipped to stores in time, he called in on his secret weapon: every employee at Access.

Any other time, his skeleton crew could handle the packaging and shipping, but not on day one. Most of the developers were salaried. Everyone else was pretty cheap. So for one day, he sent everyone in the company over to the warehouse, and the entire company packed up the game. I shifted between slipping the liner art into the front cover of the jewel case and putting disk #3 in the case.

Remember: if you already have a sunk cost in staffing, and it would cost an inordinately large amount to bring on temp staff to handle a job for you, screw the temp staff. Use your currently sunk cost.

It was an interesting experience that led me into my first lead assignment, Links Extreme, which is where I learned my first bit of what test should not do. It was also the beginning of the end for many things. More on that later.

By the way, if any old Access/Microsoft cronies read this and see mistakes, please post them in the comments so I can correct them. Thanks.

Fable: Great with one exception...

I borrowed Fable on Saturday, and beat it last night after exactly 10 hours of gameplay. I enjoyed it, and will buy it when it becomes a Platinum Hit, but they made one design decision that pissed me off to no end.

<----- WARNING: SPOILERS FOR FABLE AHEAD ----->

When I beat the end boss, my character was pegged good. At the end of the game, you are given a choice between killing your sister with a magical sword, or casting the sword into a swirling vortex and making it go away forever.

I chose to throw it away, I got the good good ending, and skipped the end credits.

Turns out that if you skip the end credits, you can't keep playing the game. That pissed me off.

So, I reloaded the last autosave, beat the end boss in 4 minutes, killed my sister, got the bad good ending, and then waited for fifteen minutes for the end credits to end. I don't know how much extra crap they could have put in the end credits. Who cares that you had Chinese takeout 2,828 times during the making of your game?

Anyway, I was so pissed after the credits that I went on a rampage. First, I went to Lady Grey's bedroom and beat the living shit out of her until she divorced me. Then, I went to every town in the game, slaughtered every single inhabitant, bought their homes, and put them up for rent.

After doing that, I was only half-evil.

<----- FABLE SPOILERS OVER ----->

In short, we should be able to skip cutscenes, credits, etc., without penalty. Forcing us to submit to your vanity scroll in order to advance in the game is just bad manners, and you should all feel very bad about it.

How I got started at Access Software

People often say that if you want to get started in the video game industry, you need to know someone to get you in the door. That is very true for 99% of the companies out there. However, once you get in the door, you need to demonstrate your skills or else you've just been wasting everybody's time, including your own. For me, it was a little more obscure than that, but here goes my Access pre-history.

For the majority of my adult life, I've worked around video games. I worked in an arcade in the now-leveled Ogden City Mall. I worked for Software Etc. in the Newgate Mall. Finally, I ended up the Hardlines Lead at Media Play in Riverdale, Utah. People came to me because I was extremely honest about the videogames that we had. If a game was a dog, I said so.

One of my regular customers came up to me and said that he just got a job offer managing a local software store. He wanted me to leave Media Play and go work for him at this new place. I'd be in charge of handling purchasing, stocking and layout for the videogaming section. After doing some digging into the place, I accepted the job offer and gave my two weeks notice at Media Play. My manager at the time made my hours a living Hell for those two weeks, but I understood why.

Evidently, I should have dug more. Within three months, my new manager was let go, the videogame section was eliminated completely, the company reorganized, and I ended up the IT Manager for Morgan Business Systems. If you've never heard of them, that's a good thing.

I was pretty miserable there. If it wasn't for a couple of co-workers, I would have gone off the deep end.

My former customer/manager knew I was miserable, so he put me in touch with Bill Biggs down at Access Software. Now, I had applied for a job at Access Software as a web developer in the past. I actually was interviewed, but the job went to someone the development team knew. However, Bill trusted my friend's judgment and interviewed me. He hired me on as a test lead on September 1, 1998.

Now, there were four issues here. One, I hadn't told my current job that I was even interviewing, let alone leaving. Two, I wasn't sure if being in test was a good fit for me. Three, the job was a significant pay cut (down to $8.00/hour.) Finally, the job was a significant distance away. I lived in Ogden at the time, and while I was within walking distance of MBS, it was a 2-3 hour bus ride to Access.

Well, I ended up using a week of vacation and worked my first week at Access while taking vacation leave from MBS. I loved it. I felt alive for the first time since I had started at MBS. So, I went in on Saturday, typed up a document with all of the admin passwords, etc., and left the document, my keys, a letter of immediate resignation and everything else on the desk of the owner.

I took a significant cut in pay to be happy, and it was the best decision I ever made. I never realized that I'd do it twice, though, but that's a story for another time.

September 27, 2004

Microsoft, layoffs and location

Some recent events have made me think about Microsoft as a company again.

I used to work for Microsoft Game Studios, and I loved it. I wouldn't trade my time at Microsoft for anything in the world. I learned more during my first six months at Microsoft than at any time before or since. I learned how when Microsoft decides to make a shift, it shifts extremely quickly, and that's due in large part to how Microsoft is structured.

Microsoft, to the world, is one company. It is a corporate identity. However, Microsoft to itself is essentially a holding company for several thousand small businesses, each usually 150 employees or less.

When a massive company like GE wants to change course, it can take years. However, because of the way Microsoft works, once the vision changes, each unit only has to change the path of 100-150 employees. It makes it very easy to adapt, because while each employee recognizes Microsoft as the big daddy company and associate themselves with that success, each employee also feels a deep bond with their current unit. What the unit wants, the unit gets.

I left Microsoft last October. The project I was working on was cancelled in March 2003, so the entire team was transitioned to working on "Amped 2".

In February 2003, Ed Fries announced to MGS that there were going to be layoffs due to a change in focus. When the Xbox first came out, MGS needed to fill portfolio holes. Now, MGS needed to be the premier developer on each platform: Xbox and PC.

In November 2003, the layoffs hit Salt Lake. The Penny Arcade guys put out a note saying that if anyone was looking for people, some people were just laid off. Daryl Welsh (who was test manager on the studio titles until late October when he became group product manager, so he wasn't really the GPM on those titles...) gave the standard Microsoft reply that didn't exactly say that nobody lost their jobs, but masked what happened.

I bring all that up in order to explain the kind of thing that happens all of the time at Microsoft.

At Microsoft, layoffs are commonplace. Either a product or a team is determined redundant or unnecessary, so the team is laid off. Once a team is laid off, they are still employed by Microsoft. Their entire job for the next six weeks is to hunt for internal jobs at Microsoft.

If you work on one of the main campuses, things get really easy for you. There's no expense to interviewing you, and there are usually hundreds of job openings inside of MS at any one time. Plus, internal layoffs are given priority on those openings. So, generally people on campus will shuffle around, and quickly bond with their new team, while still being cared for by Big Daddy Bill. Plus, there's no need to announce layoffs.

It's a different story for people who work off-campus. I don't know of a single employee at MGS Salt Lake who was laid off that found a position elsewhere in Microsoft. Several were unemployed for at least six months after their six weeks ran out.

So what happened? Why did things fall apart for the Salt Lake City office when things usually go so smoothly for the Redmond office? One word: money.

It costs money to fly someone up to Redmond for interviews. It costs money to relocate someone. Microsoft is on a cost-savings kick right now. Everything from removing towels from the showers to cutting back on office supplies.

If Microsoft won't spend $20 to restock the office supply room with pencils, what makes you think that Microsoft will spend $600 to fly an employee up to Redmond to interview them? The only way that you're going to get moved is if you are extremely better than the people competing in Redmond AND better than any potential recruits from outside. I've actually been in interview loops where someone was selected...not because they were the best, but because they would have to spend a massive amount of money to relocate the best.

Oh, well, such is life. Of course, the story of my ex-studio isn't over yet. There's another chapter of that story coming soon...

Python in Real Life Part 1

Dead Parrot - The Norwegian Blue evidently does not prefer keepin' on its back...

September 24, 2004

Weird Font Bug

I was trying to show a friend of mine at Microsoft Game Studios the map browser component I developed.

He downloaded the test application, ran it, and it crashed with the following error:

An unhandled exception of type 'System.ArgumentException' occurred in system.drawing.dll
Additional information: Font 'Verdana' doesn't support style 'Regular'.

Um, what? I can't find anything on this particular error, and we haven't encountered that error on any of our internal machines. Any thoughts?

September 23, 2004

First Windows Server 2003 Pet Peeve

I have a multi-monitor system at work. My primary monitor is a 19" LCD monitor with a maximum resolution of 1280x1024. The secondary monitor is a 15" LCD monitor with a maximum resolution of 1024x768. I keep both set to the maximum. I'm using a Radeon 7000 for my card.

So, here's the repro steps for the bug.

1) In any profile, set the resolution of both desktops to their maximum.
2) Shut down the computer.
3) Start the computer back up.

Results:
Primary desktop resolution is now at 1024x768 instead of 1280x1024.

Maintaining individual desktop resolutions is something that Windows 2000 Server and Windows XP could do. Why can't Windows Server 2003?

Limited User on Windows Server 2003

Well, I finally took the plunge. Two days ago, I wiped out my work machine that was running Windows XP SP2 and installed my MSDN copy of Windows Server 2003 Standard Edition as a workstation.

I installed Visual Studio .NET 2003 (etc., etc.) as Admin, added my user account to the "VS Developers" and "Debugger Users" groups, and that was it for being admin.

Then, I created a Remote Desktop shortcut on my user desktop to point to the Administrator account on my local machine. (It's a great feature in Windows Server 2003, being able to RDC onto your own machine as a different user.)

Being a limited user has taken some getting used to. We use GroupWise 5.5 at work, which doesn't work very well for people who aren't admins on their own machine, so I've been using the Web Access client instead. (Hopefully, the GroupWise 6.5 client works OK in a limited permission environment.)

September 21, 2004

No wonder Half-Life 2 is delayed...

3D graphics nowadays requires fairly high precision to look good... (image from http://www.steampowered.com/status/survey.html)
100.01%?
So, when did it become possible to have a percentage of respondants to a survey greater than 100%? Is Valve pulling additional surveys out of their asses, or are they just turning the knob on the head of their mascot and getting their figures that way? Or is it possible that their webmaven was figuring out the math for Source? The world may never know, but at least some of us can count.

Beware NGEN with missing assemblies...

Our primary line-of-business application has auto-update support built into it. However, it also runs nearly twice as fast once it has been NGEN'ed.

Obviously, if you update the executable, the NGEN'ed assembly won't match, so you need to re-NGEN it.

How we handled it was we set a registry key with the last version number that was NGEN'ed. If the version numbers didn't match, we'd launch a program that would NGEN all of our assemblies, then relaunch our original program.

However, the latest version included some links to some DirectX libraries. On machines that did not have Managed DirectX installed, NGEN would freeze.

Just be careful when you re-NGEN.

Why I use the BSD license

I release a lot of code to various locations on the Internet. Whenever I do a source release, however, I use the BSD license.

The BSD license is pretty simple. Basically, it says you have to include my copyright notice with your code and binary, you can't use my name to promote your stuff, and I don't give you any warranty on the code itself.

The entire license is about 30 lines of very straightforward language. Compare that to the GPL, which is about 6 type-written pages and has as much philosophy as legal mumbo-jumbo.

You may ask yourself why I choose to use the BSD license instead of the GPL, and I can sum it up quite simply. The BSD license is all about enabling people. When I release my code, I enable you to do whatever you want with it...learn from it, use it in your own products, make money off of it, and even modify it and keep the modifications to yourself. Would I hope that a person who modified my code would release the changes? Yes, but I'm not going to force them to do that.

The GPL license is what is called a "viral" license, in that if you use any GPL code in your project, your entire codebase is then subject to the GPL. If you develop some insanely profitable product, but you use a four-line snippet of code from a GPL product, you're sunk. Under the terms of the license, you need to make available all of the code for your product.

You spent a lot of time working on your product, and like everyone else, you stood on the shoulders of those who came before you. With a BSD license, I'm saying, "Go ahead and stand on my shoulders, just give me credit." With a GPL license, you're saying, "Go ahead and stand on my shoulders, but when you're done, I'm standing on yours whether you like it or not."

"Silent Hill 4: The Room" Mini-Review

"Silent Hill 4: The Room" is an unforgiving pain-in-the-ass which, while a decent game in its own right, completely forgets what made the first three games in the series compelling...a cohesive storyline that revolves around redemption for a past misdeed.

A full review will come later.

September 20, 2004

One more thing on Managed DirectX...

There is one last thing that really ticks me off about Managed DirectX...it isn't installed by default.

In order to install it, you have to run DirectX setup with a command line parameter.

The application we're going to use MDX in is an Intranet application with auto-update capabilities. However, we're already deployed, and not every person will be using the portion that uses MDX.

So, here's what I'm going to do. Since only one portion of the app uses MDX, I'm going to catch the FileNotFoundException, and use it to trigger the installation of DirectX 9.0c.

If that won't work, I'll launch the DirectX installer at app launch and set a registry key so I won't rerun it again.

September 19, 2004

Bad Weather Joke

It looks like Mother Nature has found the perfect way to keep Florida from affecting the upcoming presidential election.

She decided to wipe the state off the face of the Earth.

Democrats are not content with this decision, however. They're demanding a recount.

September 16, 2004

Odd Weather RSS Feed

From 3:40pm Today...

Feed: Weather at Ogden/Hill AFB, UT - via NOAA's National Weather Service

Title: NULL and degrees F at Ogden/Hill AFB, UT

Winds are NULL. The pressure is NULL and the humidity is NULL%. .

Glad to know that there is no weather outside...

DirectX 9.0c (Summer 2004) and Windows Forms

In the original release of Managed DirectX, the MDX team did a few things to make DirectX friendlier to Windows Forms developers.

For example, if you created a windowed device that resized, when the device resized, it would automatically resize the appropriate buffers for you. It was even called out as a desirable feature in Tom Miller's Managed DirectX book from SAMS Publishing. No longer. Now, it keeps the buffers the same size, but scales the output to the new output size.

If you want the original behavior, store your Device and your PresentParameters objects as Form-scope (or Control-scope, depending on your usage) variables. In your ResizeEvent, put the following (fill in the {} with the appropriate variable names:

If {Device} Is Nothing Then Return

If {Device}.Disposed Then Return

{PresentParameters}.BackBufferWidth = Math.Max(Me.Width, 1)
{PresentParameters}.BackBufferHeight = Math.Max(Me.Height, 1)
{Device}.Reset({PresentParameters})

Viola! Fixed.

By the way, Tom, it's undocumented behavior changes like this that would cause me not to use Managed DirectX.

Update: Added Math.Max(x, 1) to fix bug where width or height could be 0, thereby returning an extremely unhelpful exception.

September 15, 2004

OPML On The Way - Updated

My blogroll is uploaded to my domain, the permissions on it are set correctly, but I'm still getting a 404 on it. I'll check it out when I get home from work.

Update: I use WebHost4Life for my hosting. Evidently, they don't allow unknown extensions to be downloaded. Since I uploaded my OPML file as a .OPML file, and .OPML isn't a known "safe" extension, nobody could download it. I zipped it up, and changed the link to point to the .ZIP file, and now it transfers just fine.

I'm more important than my town?

My blog currently has a Google PageRank of 4/10.

My town's website has a Google PageRank of 3/10.

What am I doing here that makes me more important than my home town?

September 14, 2004

Expiring NDA's

On October 1, my non-disclosure agreement from Microsoft expires.

I was hired at Access Software in Salt Lake City, Utah on September 1, 1998 as a Software Test Lead. I was retained in the same position by Microsoft Corporation after Access was purchased in early 1999. I left Microsoft of my own accord on September 30, 2003 to work as a developer for Layton City Corporation.

Don't worry, I'm not going to give away any trade secrets or anything of the sort. However, starting in October, I'm going to start telling some stories about the sort of things that happen behind the scenes at a game company.

Mind you, however, that my stories are going to be limited to just those two companies. I am under a non-disclosure act for another game company right now, though. Maybe I'll be able to say who shortly.

September 13, 2004

Googled...Into...Spaaaaaaace!!!

A couple of weeks ago, I put a single Google AdSense ad over to the right on my blog. I figured that they were text-only ads, would probably be related to what I had in my blog, and wouldn't cause much in the way of ill will.

For the first week on my blog, Google was serving an ad for telescope accessories. I figured, hey, no big deal, they haven't crawled my site yet.

Today, I went and using the Google Toolbar, asked for a list of similar sites. The site: Light and Matter, a site for physics and astronomy texts.

Is Google saying that I'm really out there or what?

Great tool for XPath, the Query Language From HELL

XPath Explorer

I hate XPath. I think that while it does have an immense amount of power behind it, the sheer lack of usability behind it makes me think that it was designed by people who wanted job security. Kind of like a 7Mb obfuscated Perl script on acid. (Isn't "obfuscated Perl" redundant?)

Anyway, today I needed to write an XPath query to extract information from an XML document returned by a web service. (Yes, the web service returned an XML document as a string inside a SOAP wrapper...don't ask.)

Well, this was a wonderful XML document in that it had several dozen subkeys with identical names that differed solely based on an attribute value or two. Unfortunately, my grasp of XPath is limited to semi-sensible uses for semi-sensible schemas, so I was at a loss.

I found this tool after about 35 minutes of using Google, downloaded it, and had the majority of my XPath query within two minutes. The remainder took about 5 minutes of referring to page 181 of Lee Anne Phillips' "Using XML: Special Edition" from QUE.

This tool now has a permanent home in my toolbox.

September 12, 2004

Still going...

I played some more Silent Hill 4 today. (spoilers ahead)

I'm up through the end of the first pass through "Building World." The voice acting continues to improve through the game (a plus), but the game's combat-oriented roots are definitely showing.

When you are fighting a half-dozen creatures at once, it makes the game a bit more hectic.

However, the combat highlights a problem with another new feature of the series: zones. In Silent Hill 1-3, when you were moving around levels, you didn't need to worry about a load until you either crossed a cutscene barrier or opened a door. In SH4, larger areas are split into "zones," so when you cross one zone, there is a brief load while the next zone loads.

That's all fine and dandy, but there are issues during fights. Near the end of "Building World," there is a part where as soon as you exit this alleyway zone, you enter another zone and get jumped by 4 apeish creatures. One of the apeish creatures jumps past me as I hit it and knock it out. I start walking back towards it so that I can stomp on it and make sure it stays dead, but it fell down past the zone transition plane. So before I can stomp on it, the zone shifts and it's nowhere to be seen. I quickly step back, but it's awake instead.

So far, the puzzles aren't too hard. I figured it out at the beginning that the 11121, 16121, 17121, etc. numbers were really 11/21, 16/21, 17/21, etc. The 10-item inventory limit, however, pisses me off, as the inventory limit includes quest-related items. In the world I'm in now, I've got five pieces of quest-related inventory, so I'm essentially full up. It's frustrating.

The only thing more frustrating has been the constant barrage of "Dirty Disk" messages. I almost feel that Konami Japan used the "Dirty Disk" message as their catch-all error handler on the Xbox. If so, shame, because the disk I have is spotless.

September 11, 2004

Silent Hill 4 First Impressions

I picked up "Silent Hill 4: The Room" on Wednesday evening for the Xbox and started playing it last night. (Minor spoilers ahead.)

I'm about an hour and a half into the game and I'm in the Forest World, and so far it seems like there just wasn't the same attention to detail that there was in previous games.

Little things like polygons Z-fighting in your apartment (look at the top of the trash can in the kitchen while you move, or in the upper-left corner of the peephole panel you use to look in on Eileen) tend to draw you out of the immersion that was so integral to the previous games in the series.

The jerky camera movement when you hit the left trigger is an improvement over the camera shift behavior in previous Silent Hill titles, but belies the true intentions of the title. This isn't meant to be a cerebral romp through the park ala Silent Hill 2, or a deep trip into the history of the series ala Silent Hill 3. This is meant to be more of a "Fight-Or-Flight" game.

The voice acting so far is a mixed bag. Eileen sounds good, and the radio announcers sound properly monotone, but your character doesn't sound worried enough. In the previous Silent Hill games, your characters started out in semi-normal situations, and their voices wigged out more and more as the game went on. In this Silent Hill, your character has been in a trippy situation for the last five days, but doesn't sound too worried about it. Even when he finds Cynthia at the end of the Subway world, all you get is a little warble in his voice...which is soon gone. The stuttering dude in the Forest world sounds a little forced, but I can live with it.

The character models are more varied than in previous Silent Hill titles, and are a marked improvement over Silent Hill 3's monsters and NPC's. However, the characters themselves seem...well, like 70's/80's throwbacks.

I guess I'll see how the rest of the game is.

September 9, 2004

Code Dipshit

I feel like such a major dipshit right now.

I'm working on an image broadcasting program right now. A client app connects via TCP to a server. The server then starts broadcasting back a frame type (full frame, diff frame, etc.) (Int32), the size of the frame (Int32), and then the data. The client only reads as much data as I tell it I'm going to send. (I'm securing it next...first step: get it working.)

Anyway, I create the image in a MemoryStream, and then ship it over the wire.

So, I had the following code (w is a BinaryWriter, ms is the MemoryStream):
w.Write(ms.Length)

w.Write(ms.ToArray)
Any guess as to what was happening? I was getting the wonderfully vague "Invalid parameter used" System.ArgumentException thrown in my face on the client side.

I couldn't understand it. So, I put in debug code to save the image as it was sent, and to save the data as it was received.

Both files were the same size, but the one on the client had four null bytes at the beginning, and four bytes of actual data stripped from the end.

It turns out that the MemoryStream.Length property is a Long (Int64), so the BinaryWriter.Write(Long) overload was taking over instead of BinaryWriter.Write(Integer). I replaced ms.Length with CInt(ms.Length), and all was well again.

Oh, well. It took me two hours to find the bug, but at least it's fixed.

Another Grammar Pet Peeve

"Loose" means not tight.
"Lose" means you either cannot find something, or you are not a winner.

If your rules of grammar are so loose that you mix the two up, chances are you will lose me as a reader.

September 8, 2004

Developer Egos And Problem Solutions

It is my belief that when it comes to craftsmen, there are two types. There are those who have learned their craft inside and out, use the right tool for the job whenever possible, and when they don't have the right tool handy can usually do the job anyway with the tools at hand. Then, there are the hammer guys. These guys know how to use one tool: a hammer. To them, everything looks like a nail.

There is a reason that I started with that. Recently, I've been involved in some discussion threads over at Code Project that, quite frankly, have me shaking my head in disbelief. Note: I am not going to link to this moron's articles, as I sincerely hope that they will be placed in Purgatory shortly, and thus, my link would be broken anyway.

Basically, for the last two years, this "gentleman" has been using Code Project to push a replacement for HTML that he developed and named after himself. He has written his own browser for this "standard" (which only consists of text, anchor and image tags), and has written a series of articles on how to use his "standard" and how to convert from HTML to this "standard." (Before you ask, yes, I am enjoying putting the quotes around "standard." At least I'm not putting quotes around random words in the sentence.)

This person is doomed to failure not only due to his lack of thought on his "standard," but also due to the very nature of the way problems are solved.

When a craftsman developer approaches a problem, he'll use whatever is necessary to solve that problem. Need to format data for the web? A combination of XML and XSLT can help with that. Need some complex data mining? Perhaps some OLAP could be in order? Need a calendar control that only allows you to select full weeks in Windows Forms? A small variation on the stock control should do the trick.

My point is that a true craftsman developer searches for an established solution where possible, makes modifications when necessary, and only creates what is needed after all that.

The hammer guy developer is the guy I've been dealing with. Need to format data for the web? "Nah, no need. Just write a parser to convert the data from the database format to the proprietary format used by my browser here." Need some complex data mining? "Well, if you pass all of the data in my browser's format, I'll just add some data analysis stuff to my browser for you." Need a calendar control that only allows you to select full weeks in Windows Forms? "My browser doesn't utilize .NET, sorry."

If you want to succeed as a developer, it's pretty easy. Find out what the user's problem is, focus your efforts on reusing as many established, functioning, tested routines as possible, and spend the necessary time gluing them together. You'll be considered a godsend by the people who hired you.

If you want to fail as a developer, it's pretty easy as well. Simply shoehorn every problem into your one-size-fits-none solution.

September 7, 2004

Never thought I'd see the day...

loonyblog.: The greatest Archie story ever told.

A risque Archie comic? That's about as likely as a Disney artist concealing a phallic symbol in the castle for "The Little Mermaid,"...er, or not...

"Why" Doesn't Matter

I've been giving a lot of thought lately to the current state of affairs in the United States, and I think I have finally figured out when things started changing for the worse in our culture. It's the moment that we let "Why" matter.

Let me explain.

Up through World War II, if you committed a crime and were caught, you were sentenced and did your time. That was it. There was only one crime where "Why" mattered, and that was murder. If you killed someone in self-defense, it was considered justifiable homicide.

Starting in the late 1950's and going through the 1960's, however, motive started playing more of a part in judgment. Due to a rise in the visibility of mental disorders due to "shell shock" from WW2 veterans, an additional defense was brought into general use: Not Guilty By Reason Of Insanity. If you weren't in control of yourself due to mental illness, you were sent to a hospital until you got "better" instead of being sent to jail.

From there, it was a simple step to emotional distress: the wonderful "Temporary Insanity" plea. Then, a criminal's past came into play. "You see, Your Honor, my client was fondled by an ice cream salesman as a child, so when the victim bought a Rocky Road ice cream cone and walked by my client, he was actually taunting my client, so my client had no choice but to drag him into his basement and chop off his head with a dull hacksaw, refrigerate the remains and slowly devour them over a three-week period in order to protect himself."

We spend so much time trying to discover why people do what they do that the rights of the victims are forgotten. When looters are let off the hook because they weren't aware that looting wasn't wrong, we're robbing the store owners all over again. When we let murderers off the hook because the only reason that they killed was because they had low blood sugar, we're slaughtering their victims all over again.

I think that there is a simple solution to this, but it's one that judges (especially in the 9th Circuit) are unlikely to do. For each charge, tell the jury to disregard motive. Simply ask, "Did they do it? Yes or no?"

If the jury decides that they did the crime, if it is a crime that has multiple levels, such as homicide, where motive does matter, the judge should be able to make a judgment call based off of the facts presented in the case.

Finally, I think that Texas has the right idea. If you kill someone (not in self-defense) and three or more credible witnesses see you do what you did, forget years of endless appeals. You've got a date with a lethal injection. Don't be late.

September 5, 2004

Great idea, but $50!?!?!?!?!

Plantronics Engineers Customized Headset for Halo 2

I love my Xbox Live headset, I really do. But I just can't see spending $50 on a replacement Xbox Live headset when the going rate for a replacement Live headset is $15-$20, or if you decide to go for just a wired cellphone headset (which is what the Live headset is), it'll set you back $10-$15 for the same style.

September 3, 2004

Huzzah?

PvPonline.com - Strip for 09/03/2004

Excellent strip, even if the first three panels are nearly word-for-word what Patton's speech was. I would have expected at least some speech modification in the second panel to note that they're a bunch of D&D players LARPing. Also, a note or link for those of us who aren't big fans of Shakespear's Henry V would have been nice.

So, without further ado, I present a minor dialogue rewrite.

Panel 1:
I want you to remember that no bastard ever won a war by dying for his game. He won it by making the other poor bastard die for his game.

Panel 2:
Now some of you boys are wondering whether or not you'll chicken out under fire. I can assure you that you'll all do your duty. Wade into them! Spill their blood! Stab them in the belly! When you put your hand in a bunch of paintball goo that a moment before was your best friend's clean face, you'll know what to do.

Panel 3:
Alright...now you sonsa'bitches...you know how I feel. And I would be proud to lead you wonderful guys into an encounter...anywhere. And that's all.

Panel 4:
Upon St. Crispon's Day!

Xbox Live Closed? Boo-F*cking-Hoo...

Computer And Video Games - Xbox 'Closed' To Final Fantasy

I found this article linked on Blue's News, and I can tell you this much right now...Tanaka-san is not speaking the entire truth.

I was at Microsoft while the design for Xbox Live was being hammered out, and while it is true that Microsoft does control the service, Microsoft's primary goals were to prevent cheating and protect the end-user.

Every single packet is encrypted, sequenced and digitally signed. The only part of the stream that is never encrypted is the voice stream.

If you want to do a server-based game like an MMORPG, you can. If you want your server-based game to speak to other servers, they can. However, Microsoft has a few conditions. First, your server software must be certified in order to get the decryption software. That means that a very strict battery of tests is run against the server. Second, your server must be up for at least five years. Third, your server must either be hosted by Microsoft or at a Microsoft-approved hosting facility in order to protect the decryption software for Live. Finally, any updates to the server software or downloadable content must be certified the same way the original software was.

Is this a fairly heinous set of requirements? Yes. Is the end result better for consumers? Yes. Admittedly, for Live 1.0, a server was not allowed to communicate with the outside world, but that requirement was loosened with Live 2.0. Live 3.0 has been released since I left Microsoft, so I can't speak for those requirements.

Besides, Electronic Arts' three major objections to Live were not that it was a closed system. First, EA wanted to be able to disable Live for their sports titles when the next version became available. In other words, they wanted it so that if you bought Madden 2005, once Madden 2006 came out, you would not be able to play Madden 2005 online. They weren't planning on doing it, but they wanted the ability.

The second was that they had invested nearly $1 billion in their online architecture, and they were hoping to monetize the customer information they got from that system. Because Xbox Live servers host all of the downloadable content and Microsoft handles all of the billing, Microsoft takes a percentage of any payment for downloadable content and subscriptions. Right now, that works out to about $0.75 on a $5 piece of content. Not bad, considering that unlike other consoles, Microsoft eats the certification costs, which run between $20,000 and $50,000 per certification submission.

The final is that content providers don't get any of the money you pay for your yearly subscription. The reason: Xbox Live is priced in such a way that it is a zero-sum product. You pay $49.95 a year, which is enough to pay for the development work on the service, new and replacement servers, technical support, marketing and a development hot team that not only creates easier-to-use libraries for other developers, but also actively helps other studios create compelling Live titles.

So, Tanaka-san, while you could do Live, you should at least be honest about your reasons. I'm sure that your architecture has technical reasons why splitting servers between your hosting location and a MS-certified hosting location would not work. I'm sure that you don't like not being allowed to have a multiple sign-in (GamerTag, then your own). I'm sure that giving Microsoft a slice of your subscription revenue doesn't make sense to you. But Microsoft's decisions were based on what is best for the gamer, not what is best for the developer. Microsoft gets enough flack for making decisions based off of what is best for Microsoft. They shouldn't get flack for making decisions based off of what is best for gamers.

September 1, 2004

Retrieving local weather

At work, we have one primary line-of-business application called PLUS. Depending on your groups in Active Directory, portions of the application are enabled for you. For example, the business licensing portion isn't enabled for someone who primarily handles street work orders.

Maintaining a monolithic application like this may be a bit of a headache, but we have a few advantages. First, anyone can go to any desktop in the city, log in, and work. Second, security is handled at the domain level, so giving someone rights only has to be done once, and they're taken care of on our Intranet site as well as in PLUS. Third, we're able to reuse a lot of functionality within the application. Finally, since auto-update functionality has been built-in, when we get new features for departments or bug fixes, we simply prop the new build to our server, and each client pulls down the new version.

Recently, one of our department goals has been to reduce the amount of spyware and adware coming into the city. We use Spybot: Search & Destroy, Ad-Aware and SpywareBlaster to get rid of the spyware. One piece of adware we see nearly everywhere in the city, however, is WeatherBug.

Now, we can't really blame people for wanting to keep abreast of the weather, so we decided to write the weather check functionality into PLUS.

We have a form that updates a set of shared members once an hour using an XML feed from NOAA that I found out about from Ali Aghareza's blog. I don't bother with any sort of parsing, and my only validation is to check to see if the .weather member of my structure is equal to String.Empty. However, it works, and is fairly speedy.

WeatherXMLURL is set in our Globals. Currently, it's set to "http://www.nws.noaa.gov/data/current_obs/KHIF.xml".

Module modWeather


Public Structure WeatherInfo
Dim weather, temp, wind, pressure, visibility, windchill, humidity As String
End Structure

Public Function GetWeather() As WeatherInfo
Try
Dim d As New Xml.XmlDocument
d.Load(WeatherXMLURL)
Dim w As WeatherInfo
With w
.weather = d.SelectSingleNode("/current_observation/weather").InnerText
.temp = d.SelectSingleNode("/current_observation/temperature_string").InnerText
.wind = d.SelectSingleNode("/current_observation/wind_string").InnerText
.pressure = d.SelectSingleNode("/current_observation/pressure_string").InnerText
.visibility = d.SelectSingleNode("/current_observation/visibility").InnerText
.windchill = d.SelectSingleNode("/current_observation/windchill_string").InnerText
.humidity = d.SelectSingleNode("/current_observation/relative_humidity").InnerText
End With
Return w
Catch ex As Exception
Trace.WriteLine(ex.Message, "Weather")
Trace.WriteLine(ex.StackTrace, "Weather")
Return New WeatherInfo
End Try
End Function

End Module