Heinz Blows It

A while back, here in the US, some guy in Heinz marketing had a really bright idea. It went something like this...

Let's have a competition where we get people to come up with jokey slogans to go on the front of our tomato ketchup bottles.

Which was, frankly, a winning idea. I was amazed to see these cute, smart jokes on the front of the bottles. I thought it was genius. I was amazed that their marketing people actually let them get away with it.

The slogans were something like this:

Warning: Slow moving condiment enclosed
Easier To Spell Than Worcestershire
Comforts Burnt Hot Dogs
French Fries Not Included
Hides Grill Marks
For Best Results, Eat
Will Work For Food

And many many more. All funny. All just popped at you from the shelves.

Well, today I was at the store and I saw a new set of them. Ladies and gentlemen, that original marketing guy with a bright idea obviously has left the company, because now they're using it to market Ore-Ida(R) potato products.

Which sucks. Because it took a great, innovative idea that made the company look smart, intelligent and consumer savvy - in other words, not Yet Another Faceless Marketing & PR Organization Who Thinks Their Customers Are Sheep - and turned it into Yet Another PR Move From An Organization Who Thinks Their Customers Are Sheep.

Heinz - you took a great idea, and you blew it. I don't know if you got cocky, or just have morons working in your marketing dept, but you lost the kudos you gained in one easy swoop that way.

Shoulda just had a splash in the corner saying "Goes Great with Ore-Ida Fries!".

(more...)

Debugging By ESP...

I had one of the strangest experiences I've had in a long time today. Almost up there with that big switch connected to nothing that when you turn it off crashes the computer, that you hear about in all those old hacker tales...

We've had a bug that's been really tricky to find and hunt down at work. On and off, it has caused lots of the monsters and other animated meshes in the game to vanish in a peculiar way, seemingly completely at random. This has been a problem for a while now, on and off, for at least 4 months if not longer. It's so intermittent though, that it's really tough to figure out what's going on.

Well, yesterday one of the developers finally managed to track down a repro case. After playing around with it for a while, I started getting a hunch that it might have something to do with how we do the lighting on the PS2 version of the game. Messed around with some of our debugging flags, and it seemed to corroborate it; depending on where you placed the camera in the scene, and depending on which lights were visible, bodies and heads would pop into and out of view.

I figured it couldn't hurt to take a look and see if I could track it down. A complete stab in the dark, but I'm a pretty good debugger, so why not?

So I went back to my desk, fired up Visual Studio, and loaded up the game engine code.

The project opened with the exact file the bug was in on top. The correct function was on screen. And my cursor was sitting on the line of code that was wrong.

Needless to say, this was a bit shocking. I stared at the code for a bit, then a bit more, and then on a hunch decided to check and see if the code was causing a problem.

The basic nature of the bug is this:

class RenderState {

enum BufferIndex {
PointLightBufferID,
PointLightCount,
DirectionalLightBufferID,
DirectionalLightCount,
SpotLightBufferID,
SpotLightCount,
MaxBufferIndex = 8
};

unsigned char m_LastLightingPass[MaxBufferIndex];
unsigned char m_CurrentLightingPass[MaxBufferIndex];

void SetupLightingPass()
{
if (*((unsigned long*)m_LastLightingPass) == *((unsigned long*)m_CurrentLightingPass))
return;
*((unsigned long*)m_LastLightingPass) = *((unsigned long*)m_CurrentLightingPass);
MoreSetupForLightingPass();
}

Ok, so this is a bit on the hokey side, but it's only for illustrative purposes. The code does a comparison of the two lighting state buffers, and a copy of one over the other if they're different (in which case it'll also do more setup work). For speed purposes, it does the comparison in 4-byte chunks, instead of a byte at a time. Which is great, because that's the width of the bus of the CPU, so it's really happy to do that comparison that way. It's nice and efficient.

Unfortunately, there's a bug here. The problem is that at some point, spotlights were added, but the optimization wasn't updated to take it into account. This is a pretty easy and understandable mistake to make, but it's a bugger to actually find.

(In case you're wondering, probably the easiest way to fix it is like this:

if (((unsigned long*)m_LastLightingPass)[0] == ((unsigned long*)m_CurrentLightingPass)[0] && ((unsigned long*)m_LastLightingPass)[1] == ((unsigned long*)m_CurrentLightingPass)[1])
return;
((unsigned long*)m_LastLightingPass)[0] = ((unsigned long*)m_CurrentLightingPass)[0];

((unsigned long*)m_LastLightingPass)[1] = ((unsigned long*)m_CurrentLightingPass)[1];

But unfortunately that doesn't get around the problem that if the code changes again, the same problem could still arise. With a smart compiler, one could expect it to make appropriate optimizations for us. Maybe hint to it that the data is aligned to a 4-byte boundary, and the default copy and comparison operators would be set appropriately. But we're not necessarily using a smart compiler to compile the code, so these kinds of things need to be added by hand.

(For the record, like most software studios, we're using a branched version of gcc for the PS2 builds).

Visual Studio, though, lets you make those kinds of declarations in code - I've not checked if it writes out appropriately optimized assembly code though. I'm willing to bet that it does.

Anyway... this is all getting away from the point. The point is... my IDE opened to the exact line of code that was faulty. All it took was for me to look at it, and, well, follow my nose.

Needless to say, the chances of finding this bug was like finding a needle in a haystack. (And, for the record, it still remains to be seen whether or not it actually fixes the problem). For quite some time after finding it, I actually felt completely buzzed, energised, and more than a little weirded out. I even felt kind of faint (although that may have been a mixture of lack of food and my nicotine patch wearing off). How on earth could a computer do this for me?

Must have been my lucky day. Either way, it's freakin' weird. Maybe I'd seen the code, like an idiot savant. Maybe it was subliminal! Or perhaps there's a ghost that visits coders who are clutching at straws! Maybe I was meant to find that bug...

... and now, the scientist in me takes over, and has to find out what really happened.

Well, let's look at the evidence - the IDE opens whatever files I had open last time I was in the project. So I must have had that file open. And it opens scrolled to the last place that it was open... so I must have been looking at that function.

I got all the way home from work before I figured it out. Yesterday, I'd been coordinating some changes to the way we render lights on animated meshes, and there are two files in which the lighting coefficients get set up. One of them - you guessed it - was this file. And, yep, guessed again, it's in that function too. So before I filed the task for one of the team to work on, I did my usual and investigated it and what it would require. After finding out from one of the engine programmers the appropriate places to make the changes we needed, I opened up those files to verify that everything was in order, and that it wasn't a tremendously risky change.

... and just by chance, the bug was in the same function as the last place I was checking.

So, nope, not ESP. Not even anything weird - just a completely random coincidence. Serendipity, if you will.

But I still think that I may have burned through some of the karma I've built up for a while for this one. I'd better not walk under any ladders for a while :)

(more...)

End of E3

So my first ever E3 show is finally over and done with. I'm exaausted, and have sunburn on one of my arms from being stuck in LA traffic with the window down for huge long stretches of time. Shay only came down for the last day of the show, and she's exhausted now too. Finish it all off by meeting up with an old friend of mine (Colin MacDonald) which is especially appropriate as he's probably the #1 person responsible for getting me involved in the games industry in the first place way back at the tender age of 15, and it's one hell of a trip.

Highlights

  • Namco's real live Katamari, and playing We Love Katamari.
  • Booth babes (in general).
  • Midway's party at the Avalon, and the Best Buy sponsored Inside E3 party the next night at the same place (much more my kind of music the second time).
  • Seeing people actually getting a kick out of playing Suffering: Ties That Bind.
  • Normal E3 members trying to compete with Booth Babes on the looks dept.
  • Seeing old friends who live in the LA area / came into town for E3.
  • Hellgate: London, Prince of Persia 3 (let's hope it's a little less combat-heavy than POP:Warrior Within), Quake 4, Burnout: Revenge, The Godfather.

Best Booth

For my money, EA stole the show with the best booth by having a 360 degree wraparound screen on which they projected movies, including a 360 degree render of a game of Burnout: Revenge. You could see EVERYTHING, and all of a sudden it got very real. Similarly, The Godfather was very impressive in 360 degree surround visuals, even though as a cinematic experience it was particularly weird to have to whip around 180 degrees to find out who was shooting someone, instead of seeing a cut to provide the same information. Fascinating, fantastic stuff.

(more...)

Writer's Guidelines: Rules for Writing High Tragedy

As part of an occasional series (i.e. when the mood takes me), I'm writing analyses of story genres and components. The few I did were on Rules for Writing Classic Teen Movies... an analysis of the new category of Not Quite Teen Movies (or Anti-Teen movies)... and the observation that Ferris Bueller's Day Off isn't really a teen movie at all - in fact he's the Trickster archetype - aka Loki.

From here on out, I'm going to put "Writer's Guidelines:" at the beginning of posts which perform this kind of analysis. Note - these are all my own personal definitions, and might not agree with the traditional definitions (some of which go back several thousand years to people like Aristotle). As such, they come from the perspective of ... well... if you wanted to write a classic movie - the kind that would have people talking about it for decades - how would you do it? This is my take on it. It may be wrong in places - but that's what the Post Comment button on the blog is for.

So without further ado...

What is High Tragedy?

Let's look at some examples of what is tragedy, what is high tragedy, what is retro-tragic (i.e. doesn't make itself apparent as a tragedy until after one knows the story), and so on:

What Dreams May Come, Titanic, >Gods and Monsters, Episode 8 of the new series of Doctor Who (Father's Day), When the Wind Blows, Moulin Rouge and The Messenger are all examples of high tragedy stories.

Shakespeare In Love, and Romeo and Juliet are simple tragedies - not high tragedy. Star Trek 2: The Wrath Of Khan crosses into tragedy (or is it high tragedy?) when Spock goes and gets himself irradiated. Similarly, in Star Trek 3: The Search For Spock, the destruction of the Enterprise is a tragic moment.

Some stories are not obviously tragic at first, but become so as the story evolves - Requiem For A Dream, Leaving Las Vegas, Dead Ringers (although it becomes high tragedy at the end).

Some movies paradoxically don't actually become tragedies until the second watching. Examples of this include Donnie Darko, Memento, City Of Angels. They may have elements of tragedy in them, but to take in the full scope of the high tragic story arc, one must have global view of the story - and that requires familiarity with it while watching it.

So What Makes Something High Tragedy and not plain Tragedy?

Tragedy is a story which leads to an unhappy ending for one of the characters. Most importantly, the stakes must be high (death, loss of friends, family or loved ones, unrequited love) - losing money at a gambling table is not tragic; whereas a gambler who cannot control himself and so leaves himself millions of dollars in debt to a loan shark who will kill him is.

The difference between a tragedy and a high tragedy is that in high tragedy, the audience knows well in advance that the only way out for the characters is the unhappy ending. The perfect high tragedy establishes the stakes and the unhappy ending at the beginning of the movie, and the rest of the movie only serves to explain what events lead up to the ending.

The high tragedy ending must be telegraphed; that is, it must not be a surprise. It must be an obvious conclusion to the events we are seeing onscreen. Unlike the murder mystery, surprise is the last thing we need in a tragedy. There is no twist at the end. The job of the writer is to start with hints at the ending, provide a multitude of ways out of the situation, and then to prune them all away one by one until by the end of the story there is no choice left to the tragic figure but to conclude the story as the audience already knew it would.

Tragedy is not about surprises. It's all about giving the audience exactly what you told them would happen.

Pacing then becomes one of the most important elements to the story; for maximum emotional impact, ways out of the scenario must be presented, and then each one must be taken away. They do not all have to be presented at once, but they must be logical and consistent with the story, or else disbelief will be broken.

There's an important side-note to this, and it gives us the difference between a heroic tragic figure and a non-heroic tragic figure. The heoric tragic figure makes a choice - through either deliberate action or inaction - to help others by facing the unhappy ending head on. The non-heroic tragic figure is either oblivious to the plight of others, does not care, or tries to take them down with him (which, by the way, is the hallmark of your traditional good vs. evil morality adventure yarn - viewed from the right perspective, the villian is a tragic figure, because the good guy always gets the bad guy in the end).

Not all tragedies must end the story at the point of tragedy; however, the climax must be tragic. For example, in What Dreams May Come, Robin Williams plays the tragic hero character Chris. The story is high tragedy, because we are shown Chris's wife Annie's unending descent into depression and eventually suicide - and Chris's increasingly failing attempts to reach her and bring her back end with him deciding to succumb and live in the hell of her own making forever. However, unlike other high tragedies (Gods and Monsters, the ep. of Dr. Who, The Messenger, Titanic), the story does not end with the tragic ending; Chris's sacrifice causes his wife to recover - and she brings him back.

(I really need to come up with the right name for this kind of reversal ending - there has to be one, but I just can't think of it right now).

Gods and Monsters is a high tragedy because James Whale (Ian McKellen's character) starts the film out terminally ill - and you know it's only a matter of time.

When the Wind Blows is high tragedy because we all know that trying to survive nuclear war is pretty much futile. And when the two main characters become sick from radiation poisoning, one knows that the end is near. The story is made all the more poignant by the fact that even if they don't know sometimes how deadly the situation they're in is (e.g. going outside and walking through the ashes of the fallout) - we do. And so the next domino falls - and the next - until the story reaches its end, back where it began.

Closely related to the High Tragedy story is the Descent story - examples include Falling Down and Requiem For A Dream which compete for the position of best cinematic example of the genre of all time.

The Descent story type is almost the exact mirror of the High Tragedy story. In a Descent story, the character's own choices and actions are the direct cause of their problems - with external influences only serving to push the character from one faulty judgement to the next, leading inexorably to the Tragedy's unhappy ending. The Tragedy is the opposite, in that the external influences serve to limit the character's choices, removing their options. (As such, Leaving Las Vegas is much more of a Descent story than a Tragedy).

Descent stories share elements of morality tales, by hammering home the "crime does not pay" moral conclusion in illustrative form.

I'll add more to this later, including a discussion of melodrama and its importance in tragedy stories.

(more...)
#fiction, #script writing, #story
Bookmark the permalink.

Best episode of Doctor Who ever

I just watched Father's Day, which frankly has to be the best episode of Doctor Who ever made. Ever. I mean it - it literally doesn't get better than this. (Although I have a sneaky suspicion that they're going to try to prove me wrong by the end of the new series).

I think I nearly bawled for the last 15 minutes of the damn thing. And, come to think of it, for about 30 minutes afterwards I was still pretty heavily affected.

It had everything I normally look for in a time travel story (especially when I'm trying to write one). I'm just floored. Simply floored.

It was even better than Dalek, which is one of the most amazing stories ever shown on Doctor Who as well. Except this time, the direction, the story, the acting... everything was flawless. (Well, ok, the music was a little badly done in places... but it's hard to notice with all the fantastic acting that's going on).

Paul Cornell, Joe Ahearne, please, take a bow. Joe's rapidly becoming one of my favorite writer/directors of all time, and Paul already was one of my favorite writers (along with Kate Orman and Chuck Palahniuk).

Sheer magic.

(more...)

subscribe via RSS