Customer Experience Software Development

What Photography and Programming have in Common

Ladies and gentlemen, allow me to share with you a tale of two photographers.

My fiancée and I were featured in a piece for our local newspaper a couple of weeks ago. The columnist wanted an image to accompany her content, so a photographer was sent to my apartment to take a photo of me and my bride-to-be.

This went down about the same way I expected. Some nondescript dude with a camera walked in, looked around the room for all of about six seconds, arranged a semi-interesting shot involving a mirror, snapped a few pictures and left. This took around ten minutes.

A few days later, the writer for the aforementioned article called back and asked if she could send over another photographer. Apparently the shot the first guy had lined up was too similar to a shot the newspaper was running on another article, on the same day, in the same section, so they needed a new one.

The second photographer was Christopher Pike.

Christopher ran things a bit differently. After introducing himself, he spent a few minutes looking around my humble abode and the surrounding area. He then asked my fiancée and I what we thought of a few potential shots, and started taking pictures. A lot of pictures. We posed on our balcony, on a bench, near a wall, next to a fence, under a tree, and probably in other places that I’ve since forgotten about. Every time Christopher noticed something that might make for a cool photo, he asked if we wouldn’t mind posing for it. In total, this process took over an hour.

It’s important to note here that the first photographer and Christopher were both freelancers hired by the newspaper. They were probably both paid the same amount. But while the first guy spent ten minutes taking a picture he had decided upon in advance, Christopher spent about seven times that long experimenting and looking for the perfect shot.

What does this have to do with programming?

Just like photography, programming is a craft.

That first photographer, the one whose name I can’t remember, was just in it for the job. The editor wanted a cute photo of a cute couple, so our unremarkable photographer took one and took off.

This is how a lot of equally unremarkable coders look at programming. You need a function that converts X inputs into Y outputs? Sure. Let me whip up a quick algorithm that does that. Done. What’s next?

Christopher, on the other hand, was there to take great pictures. He was passionate. He approached photography as a craft. Yes, the output was a photo that he could sell to a newspaper, but believe me when I tell you that’s not why Christopher is a photographer.

This is how I look at coding (and hopefully how you do too). You need a function that converts X inputs into Y outputs? Ok, let me consider the context, ask a few questions, then create a solution. Functionally, it will be the same as Joe-first-photographer’s solution, but as a programmer that cares about his craft, I took the time to:

  • Verify that yes, a single function is the best solution.
  • Keep future maintenance and extensibility in mind.
  • Write clear, reusable code.
  • Add useful comments where necessary.
  • Refactor my function to be as simple as possible.
  • Change all my spaces to tabs to match the existing code-base.

Which photographer would you rather hire? Which programmer would you rather have on your team?

Software Development

Software Bundles, Independent Developers, and More!

Over the weekend, I picked up the Humble Indie Bundle, a pay-what-you-want download for five six games created by independent developers. I love these bundles! I get a bunch of cool software, the developers get a lot of blog coverage/followers/supporters/fans (let’s just call it social capital), and a cut of the proceeds go to a pair of great causes (Child’s Play and the EFF). It’s win-win-win. And it shows one of my favourite things about software:

Software is different.

No other industry can really get away with something like this. Can you imagine if those had been board games instead of computer games? Think of the logistics involved! Impossible. But software can get away with it, because once software has been developed, it costs almost nothing to make copies of and distribute. Different. Which reminds me:

Independent developers are special.

You don’t really see major publishers do this. You could make a case for Valve, because they really have this online-distribution thing figured out, but you’d never see EA partner with Blizzard for a heavily-subsidized package including Dragon Age and Starcraft 2, let alone see them donate the majority of it to charity. Independent developers can do this because they don’t operate under the same rules as major publishers, and they’ve found a loophole in traditional business beliefs that allows them to do something awesome that benefits them, their users and anyone touched by the charities they support. Special.

Now bear with me for a second, and let’s try to think of a market that sells and distributes software with a lot of support for, or even a huge bias towards, independent developers. Wouldn’t that be an ideal platform for more of these bundles? (Don’t cheat and say Valve; I know they’re cool, but that’s praise for another day and we’ve already singled them out above).

The App Store.

Apple’s App Store for iPhone/iPod/iPad contains around 200 000 applications* and is very popular among independent developers (I couldn’t find numbers for this, but polling my iPhone I’m going to wager it’s certainly a majority). With that many applications, developers could really use some extra exposure, and the visibility Apple is able to provide through the App Store is surreal. How long would it take for most iProduct users to hear about a group of independent App Store developers packaging a few apps together for the sake of charity if it was promoted directly through the App Store and/or Apple’s marketing team? Days? It would be a sure-hit.

Users would get more great software in a convenient, affordable, socially-rewarding package. Developers would get more copies of their app out there, and a compounding amount of exposure (word of mouth is big on iProducts). Apple would get some much needed love from their developers and their users (if anyone is hurting for karma right now, it’s Apple). And just think of the fantastic interface Apple’s brilliant designers could craft by integrating bundle-purchasing straight into the App Store!

There is a huge opportunity here.

Am I the only one that sees this? Tell me I’m not crazy.

* They announced at the iPhone OS 4 event back in April that they were over 185 000, so if 200 000 hasn’t been reached yet it’s not far off.

Software Development

A Cool always-on-top Keyboard Toggle and a Lesson in Software Tool Development

The other day, I came across a problem I frequently seem to encounter. I had a group-chat in Skype that I wanted to follow, but not necessarily contribute much to, and due to how often it was updating, it was getting annoying to have to constantly stop typing in my full-screen IDE and alt-tab back to Skype. I realized that it would be much more efficient if I could somehow temporarily designate that Skype window to always stay on top of the screen, the same way Task Manager does. That way I could be working away in my IDE, and when there were new messages in Skype I simply had to glance over, rather than alt-tab.

Naturally, I assumed this was a problem that was already solved, and a little Googling led me to a handy always-on-top toggle script that is activated using a hotkey. Perfect! Download, install, run, and within a few seconds I had my desired functionality… only the hotkey that the script uses to toggle the always-on-top property is ctrl-space, the same shortcut used for the absolutely-necessary auto-complete feature in Eclipse.

The script doesn’t provide any means for changing the hotkey, so I had to get a bit more creative. I set out on what I thought would be the difficult quest of figuring out how this script was made and re-making it with a different hotkey (I ended up using caps-lock). To my utter disbelief, it only took about five minutes. There were a few reasons why this was so easy to do, which I’ll get to in a moment, but first here is the script in case it might be useful to anyone else:

Download my Capsatop utility for Windows XP

No, I didn’t test it in Vista or Win7. Yes it might still work; please let me know if you try it. If you’re curious about doing this in linux or OSX, you’re on your own, but I’d love to hear about that too :~)

Now then, the rest of this post will be about why this was so easy to do, with a few lessons about good software tool development practices. For starters:

It helps when things are open-source.

That handy page I mentioned earlier was kind enough to mention that their ctrl-space script was made using a tool called Autohotkey, which I’d never heard of, and that it was only one line, which they provided:

^SPACE:: Winset, Alwaysontop, , A

So I downloaded Autohotkey, and braced myself for the impending learning curve. Fortunately, I was in for a shock:

Autohotkey is an incredibly intuitive tool.

It literally took me under two minutes to install Autohotkey, grok how it worked, and recreate the script with the line of code above. I credit this entirely to Autohotkey’s development team for putting together a really easy-to-use slice of utility software. Here are the things it got spot-on:

It installs an editor and a converter. No sense trying to put these two functions together into one larger (and surely more complicated) application, and their respective purposes are obvious right from their executable names.

The editor literally doesn’t let you do anything other than type out .ahk files. This is key; don’t let me fret over which filetype to save in, force me to use one option that is guaranteed to work.

The converter has a dead-simple UI. A field asking for an .ahk file, a field for specifying the path for the .exe, and a giant button that says “Convert”.

Without reading any documentation or having any experience with this tool, it took minutes to accomplish a simple, but specific task. All software should work like this. I shouldn’t have to read any documentation to figure out how to use the core feature of your application. That said:

Autohotkey’s documentation is excellent, from what I saw.

I say “from what I saw” because I didn’t have to look at very much of it (which, again, is the way it should be). All I wanted to do was change the hotkey I already knew about from ctrl-space to something more convenient, so I pulled up the AHK docs, which had a very convenient Hotkey pages summarizing exactly what I wanted to know (and nothing more).

All I had to do was skim through this one, short page to find a better hotkey. About two screen-lengths down I saw a note on how to disable caps-lock (this is perfect; I never use caps-lock—ever—and it’s a nice big key that’s easy to hit). Even though the docs actually use num-lock in their welcomely-concise code-sample, I was able to take a pretty reasonable guess at the syntax for disabling caps-lock and how to override it to run my always-on-top line. Back in the editor, I made the small change, switched back to my converter and hit that big, impossible-to-miss convert button again (without re-entering my filenames) and… it worked on the first try! I was speechless — five minutes.

Software Development Web Technology

Improving Performance in Flex and Scaling BlazeDS

I gave a talk today at work about Flex and BlazeDS, and in particular how to scale both to perform well during high-volume, real-time communication with a Java-based server (in the area of thousands of messages per second). Here are the most helpful bits from my presentation and the ensuing discussion:

Stick to StreamingAMF.

When it comes to real-time data transfer, StreamingAMF is really your only choice for a high-performance endpoint. It offers two simple advantages:

  • Streaming connections allow for true push, rather than less-effective fast-polling.
  • AMF is a binary protocol, so less data is transferred across the wire.

If you need a more thorough round-up of endpoints, I highly recommend DevGirl’s excellent endpoint explanation.

Batch messages going through BlazeDS to save bandwidth.

BlazeDS adds significant overhead to each message sent across the wire. With thousands of messages per second, this adds up to a very significant amount of bandwidth usage, to the point that performance will be adversely affected.

To compensate for this, buffer consecutive messages together and send several at once. Even a simple timeout that buffers message content for 10ms before sending it all as a single message will save an incredible amount of bandwidth, and a smart buffer that adjusts its timeout based on message activity will do even better.

This is easy to implement, and likely the biggest performance optimization available in a high-volume situation. Definitely worth doing if bandwidth and performance are a concern.

Override default BlazeDS connection settings.

BlazeDS sets two interesting connection limits too low:

First, the <max-streaming-clients> property is used to limit the number of clients that can simultaneously stream from the same server. BlazeDS limits this to 10 by default, so if 11 users connect to your application at the same time, that 11th one won’t get through. This is a serious fault, but we can raise the limit as long as we’re smart about how high we set it.

The reason there is a limit at all is that all connections in BlazeDS use blocking IO. This means that the maximum number of connections Blaze will support is limited by the maximum number of threads in the application container, since it will always require one thread per connection. Fortunately, modern containers support much more than 10 concurrent threads; Tomcat 6, for example, reserves 150 by default and even that can be boosted.

So the rule of thumb here is that you don’t want your connections in BlazeDS to outnumber the threads in your container, and that’s what you should base this limit on. If you require more than a few hundred concurrent connections, you’re out of luck and you’ll have to either wait until Blaze implements non-blocking IO connections, or upgrade to LiveCycle.

The second, much-less-serious configuration is the <max-streaming-connections-per-session> property, which is used to limit the number of concurrent streaming connections a specified browser can support. If this number is exceeded, new connections will not open on the same client. BlazeDS defaults this value to 1 for all browsers, so if a user opens two instances of your streaming app at the same time, on the same machine with the same browser, the second instance will not open.

This limit is dependent on the browser, and many do actually have a hard limit of one single streaming connection at a time. However, newer versions of Internet Explorer/Firefox/Safari, most versions of Opera, and all versions of Chrome support multiple concurrent streaming sessions. To take advantage of this, override the limit in your services config; I’d suggest looking at Patrick Heinzelmann’s awesome RemoteServices example to grab the specific browser numbers and a nifty code sample.

Get low-level with Flash Player.

There are probably a lot of neat Flash Player performance hacks that I’m not aware of, but here are two I’ve figured out so far:

The default frame rate in Flash Player is not very high. I’m not entirely clear on what it is; I’ve seen some sources say 24fps, some say 12fps, and some say it’s completely dynamic. Depending on what you’re doing, you may consider boosting it to draw more often. In particular, this can lower the worst-case latency between a message being triggered, processed and displayed. The flip-side here is that a high frame rate will raise your CPU usage, so that’s a trade-off to keep in mind.

Secondly, for the longest time I was updating the screen whenever I had new data to display. In retrospect, this was ridiculous. How do I know if I’m updating more often than the screen is being refreshed? How do I know how long it will be until this update is actually blitten* to the screen?

A much less naive approach is to make screen updates on the ENTER_FRAME event. This is dispatched right before Flash Player refreshes the display, so it ensures that whatever you do here will be instantly reflected on-screen. As long as this is the only place you’re doing screen updates, you know that you are doing exactly one update per screen refresh, which is ideal provided you’ve calibrated your refresh rate to match how often you receive updates.

The Profiler is your friend.

After all the above tricks have been exhausted, if you still need a performance boost, there’s always code-level optimization. Things like unrolling loops and minimizing allocation using the “new” keyword will add up eventually. A good way to find out which areas will benefit most from such refactoring is to use the profiler that comes with Flex Builder.

The profiler will allow you to view object allocation stacks and method performance. The former is a great way to find memory leaks and the latter is fantastic for finding out which methods are the slowest and thus most qualified for optimization. If you have any curiosity at all about this sort of thing (and you should!) I heartily encourage you to open up the profiler and fiddle around with it a bit; it takes a bit of ramp-up but once you have it figured out it’s a totally indispensable tool.

Hopefully this will be helpful to someone out there. Flex and BlazeDS are both very well documented by Adobe, but these were the handful of cases where I had to go well out of my way to find workable solutions.

* blitten: Past tense of blit.

Software Development Web Technology

Software is all about Context

Context is a very important factor in software development. Knowing the conditions under which your software will be used is an integral part of crafting a positive experience for your users. Many companies take this to heart and create truly engaging software that really connects with its users, but the vast majority miss the mark. While I’m sure I’d have no trouble pointing out a myriad of context-related issues in software made by Average Joe Developer, today’s focus will be on showing that even the top names in software aren’t perfect.

Exhibit A: The iPhone’s

Let me tell you a story. A few weeks ago, the fiancée and I were scheduled to meet with a potential wedding venue early Saturday morning. Given that it was a bit out of the way and we tend to oversleep, we thought we’d be smart and set an alarm using the iPhone’s default clock app.

So Friday night, we set an alarm thinking it would wake us up Saturday morning. It did not; it turns out the alarm we set was for weekdays only! While this was entirely our fault, I’m still going to call Apple out on not taking context fully into account: when we set the alarm, why didn’t the app warn us that the alarm wouldn’t go off the next morning? I would imagine it’s very rare that anyone sets an alarm more than a day in advance. It’s much more likely that when someone sets an alarm at night, they expect it to wake them up the next day. This is a case where a neat feature is actually an annoyance because context isn’t handled as well as it could be.

Exhibit B: Google Maps

Continuing our story, while I was frantically trying to get ready I was loading Google Maps to get directions to our appointment. After punching in the address and asking it to route us there, Google Maps told me the trip would take over 9 hours. I freaked out! We don’t have 9 hours, we have 30 minutes; is this the right address? Did we accidentally book an appointment at a venue 9 hours out of Ottawa?

Actually, it turns out I had Google Maps set to give walking directions. Again, my fault, but again, where were the developers on this one? Did they really think I wanted to walk over 9 hours to get somewhere? Why not recognize that I was probably looking for driving directions and put a message at the top of the screen asking if that’s what I meant?

(For the curious, this story did have a happy ending: we made it there a slight 15 minutes late, and this was the venue we eventually chose for our wedding.)

Exhibit C: Firefox’s Spell-Check

Firefox is an incredible piece of software. It is currently the browser of choice for about one quarter of all internet users, and in many ways helped to revolutionize the web browser market. But one area where it hasn’t really advanced as far as it could have is its built-in spell checker. I don’t have a fancy story for this one; the data speaks for itself. Here is a list of words that show up as spelling errors in Firefox 3.6:

Some of the internet’s most popular websites:

  • YouTube
  • Facebook
  • Myspace
  • Flickr

Well-known web technologies:

  • Skype
  • Silverlight
  • Webkit
  • WordPress, CMS
  • PHP, CSS (it gets HTML)

Very common computer words:

  • Inbox
  • USB

Extremely successful desktop software:

  • Photoshop
  • PowerPoint

Apple products:

  • iPod, iPhone, iPad
  • Macbook
  • iMac
  • OSX (it gets Linux and UNIX)

These are all very common words in internet parlance, and it’s ridiculous that they are highlighted as possible spelling errors. Why not add them to the dictionary? A simple white-list that could be crowd-sourced to the community seems right up Firefox’s alley; I wouldn’t be at all surprised to see this addressed in a future release.

What can we learn from this?

My main take-away here is that context is a big factor in software development, and one of the hardest to get right. Even the big guns have room for improvement, which means the rest of us likely do as well.

Software Development

iPhone OS 4.0 Predictions

This week’s entry is for the Apple fanatics, and iPhone owners (or potential iPhone owners) in particular.

There was a post over at TUAW last week encouraging readers to weigh in on what may or may not be present in the forthcoming iPhone OS 4.0. I missed their deadline for submitting comments, but read on to hear my thoughts anyway — I’m going to talk about a couple of things I’d like to see happen to the built-in Maps app.

Voice Navigation

There is a big market for GPS-like turn-by-turn directions on the iPhone, and plenty of companies both big and small have thrown their hats in with varying features and price points (an excellent comparison of such apps is available at Pocket GPS World). While this is enough to show that users really want voice-navigated directions on their phone, the big reason I think this will happen is that Droid users already have this behaviour built straight into Google Maps. This is a big feature, and the difference between having it available by default on the Droid and as a paid app on the iPhone is significant, and something I think Apple will want to address.

Augmented Reality

There are a lot of apps designed to help users find nearby points of interest. Some of the more recent ones have started a trend called augmented reality, which is when a live feed of the camera on the phone is used as the background and information is overlayed on top of it based on what direction the user is facing. With the iPhone’s accelerometer and compass, this technique has proven to be remarkably accurate and holds a lot of “wow” factor; something Apple has consistently been a fan of.

Since most of these apps are simply wrappers for the Maps app, why not cut out the middleman and blend an augmented reality feature into Maps by default? This would be Apple’s first entry into the growing augmented reality market, and would really up the ante for developers who currently offer augmented reality mapping features. Apple is all about shaking things up, so while this is probably pretty unlikely it wouldn’t be entirely out of character.

Your turn!

I’ve given my thoughts about the Maps app, which I think will net a big update come the next iPhone OS release. What do you think will be added/changed/removed in iPhone OS 4.0?

Software Development

Adobe “gets” Integration

In the world of software development, I submit that the hardest thing to do is to continue developing your code after it has been integrated into someone else’s code, which they are also continuing to develop.

The challenge here is that you and this other person are now co-dependent. If you break the build, it’s broken for both of you, and vice-versa. If your next feature requires some "almost finished" feature from the other party, your deadline depends on their deadline. This isn’t so bad with literally you and one other person, but what if you’re part of a large team working on one product, and the other person is an entirely different team working on a different product altogether, with different priorities and different deadlines? That’s just asking for headaches.

Adobe has some kind of magic handle on how to do this really well. Let’s start from the beginning: for a while, they just did Photoshop, which was pretty neat. Then they added Illustrator, a great Photoshop companion. Interoperability was a bit rocky at first, but now it’s a piece of cake moving a design from one tool to the other.

Then from the opposite direction, they released Flex Builder. Web mark-up integrated with Flash. Adobe gets it right again, bridging the gap between two like technologies. But do you know what made things really interesting? Catalyst.

With the release of Catalyst, suddenly everything has to work together. Designs made with a combination of Photoshop and Illustrator have to be compatible with Catalyst, which has to play nice with Flex Builder, which relies on Flash. This is a lot of complex products interacting with a lot of complex technologies; it’s an absolute mess of dependencies. And you know what? They made it work. Seamlessly.

Take a moment and appreciate how awesome that is. Imagine what would happen if they wanted to add a new feature to Catalyst. First, there are the normal issues that may come up in Catalyst:

  • Will this break any of Catalyst’s existing features?
  • Does the user interface match the rest of Catalyst?
  • Does it introduce any new bugs into Catalyst?
  • Does it open up any regressions in Catalyst?
  • etc

Then, you have to consider what this will do to any incoming Photoshop/Illustrator design files:

  • How will new design files take advantage of this feature?
  • How will existing design files react to this feature?
  • Does the underlying design file format have to change?
    • If so, does that cause any bugs/regressions in Photoshop or Illustrator?
    • Who is expected to report/fix/test these issues? The Photoshop/Illustrator guys? The Catalyst team? Some combination of both?
  • Besides that, is there any work at all required on the Photoshop/Illustrator side?
    • If so, do the Photoshop/Illustrator guys have time budgeted for it?
    • What parts of the Photoshop/Illustrator changes depend on what parts of the Catalyst changes?
    • Can any of the Photoshop/Illustrator work be done in parallel with the Catalyst work? How much?
    • How will this affect the deadline?

And of course, that same list applies to how this feature affects the content Catalyst exports for Flex Builder. And that’s just the obvious dependencies &#8212 it gets even worse:

  • What if a team can’t fulfil their side of the changes? Reschedule? Cancel? Release anyway?
  • If one team is late, what does that mean for the others? What if several teams are late? What if everyone is late?
  • What happens if the release cycles between any of these products don’t match up?
    • Can we release Catalyst with its changes before the changes to Photoshop/Illustrator/Flex Builder/Flash are released?
    • What if a user upgrades one product but not another? For that matter, how backwards compatible is this for outdated versions of any of the products?
      • Aren’t there thousands of possible version combinations? How many should be tested? Who’s managing this?

And this is just what I’m thinking of as I type. I can’t even imagine what a mess it must be to coordinate features in all these applications. How do you even measure what effect a new feature in one product will have on any of the other products’ thousands of features?

I don’t know how Adobe does it, but they do it and they do it well. If they can keep this up, they’re going to be around for a very long time.

Gaming Software Development

Two things we can learn from the Left 4 Dead 2 Demo release debacle

1. How not to delay a release

The thing about deadlines is that sometimes, even when you’ve done everything you possibly could, they still get missed. It’s not always your fault, but nobody cares; once it’s late, everyone will blame you. And if you’re Valve, they will be loud and bitter and increasingly annoying.

But that doesn’t mean it’s ok to be stupid about how you postpone the release.

For those who of you who weren’t sitting on the edge of your seats from Tuesday afternoon until Wednesday evening, here is what happened:

  • Oct. 23rd 11:30 PST — Valve announced that the Left 4 Dead 2 demo would be available on Oct. 27th for anyone who pre-ordered the game.
  • Oct. 27th (early morning) — The release was scheduled for noon PST.
  • Oct. 27th noon PST — The release was postponed until 1pm PST.
  • Oct. 27th 1pm PST — The release was postponed until 2pm PST.
  • Oct. 27th 2pm PST — The release was postponed until 3pm PST.
  • Oct. 27th 3pm PST — The release was postponed until 11pm PST.
  • Oct. 27th 11pm PST — The release was postponed until Oct. 28th at 6am PST.
  • Oct. 28th 6am PST — The release was postponed until 1pm PST.
  • Oct. 28th 1pm PST — The release was postponed until 2pm PST.
  • Oct. 28th 2pm PST — The release was postponed until 3pm PST.
  • Oct. 28th 5pm PST — The demo was finally released.

This demo has been heavily anticipated for weeks, so needless to say people were very excited about it. After the first delay, most people were probably still too excited to care. After the second and third, the general populace was getting annoyed, but still had faith. But by the time it was delayed until 11pm (that’s 2am for us east-coasters!) people were starting to get quite upset. What was Valve doing that suddenly needed an extra five hours after already pushing the deadline by one hour several times? The comments on the official steam community group were shut down due to the sheer rage of Valve’s loudest fans.

When they missed the 11pm deadline, that’s when things got bad. Imagine living on the east coast and staying up until 2am to play the demo the moment it’s released only to find that shortly thereafter, Valve delays it until the following morning. Then waking up that morning only to find the deadline pushed until the afternoon!

And it didn’t end there. Even in the afternoon, Valve promised one more hour twice, then stopped updating anyone altogether before finally releasing the demo two hours later after a grand total of 8 missed deadlines in under 30 hours.

Now the proper way to handle a missed deadline is to give it one solid push, not to string it along for a day and a half. If Valve had come out on Tuesday and said “Sorry everyone, but we’re making some last minute changes to our servers and the demo won’t be ready until Thursday” then sure there would have been a bit of backlash, but nothing like what actually happened. Since this is the first push, the community can still have confidence that the new deadline will be met. And imagine how excited everyone would be when on Wednesday evening Valve releases it earlier than they had cited!

This was a serious mistake on Valve’s part. I’m not sure what went wrong or why they kept thinking they could fix it in under an hour, but they should have known better. They should have given it a big estimate with plenty of buffer in case more things went wrong — this would have been less stressful for everyone, and if it really only took an hour to fix, they could’ve just released it anyway.

2. Why it’s important to make awesome products

Because it makes people forget about things like a botched release date.

There’s no denying that the demo delivers. The new content is fantastic, and there’s just enough of it to give gamers a sense of what the full game will contain. It’s all kinds of fun, and the nature of Left 4 Dead means that the two levels available will be worth playing plenty of times — easily enough to satiate the cravings of many between now and the full-game release. A smashing success!

But back to my point. The blog coverage for the Left 4 Dead 2 demo between the afternoons of October 27th and October 28th was completely negative. Anger about the constant delays, blind rage directed at Valve, and users feeling that they could no longer trust their favourite publisher. How’s the blog coverage now? Very positive — everyone’s talking about how great the demo is. A couple of days’ worth of gushing is already drowning out all the bad press from the release. In a week, when the demo is opened up to the public, will anyone care that the pre-ordered version was a touch late? Of course not! It’s here now, and it’s awesome.

This is the power of a fantastic product. The power to overthrow 2 days’ worth of bad press and replace it with accolades.

What’s your take?

Can we draw any other lessons from this experience? Will Valve? Are you still pissed about how long it took the demo to come out? Leave a comment — I’d be glad to hear about it.