Intel sponsors gamedev.net search:   
The Bag of HoldingBy ApochPiQ      
Apoch's Avatar

Apoch
XP: 64,738
Inventory
Special Items: Shpongle | XBox Live
My brain is built of paths and slides and ladders and lasers and I have invited all of you to enter its pavilion. My brain, as you enter, will smell of tangerines and brand-new running shoes.
Page:   1 2 »»

Saturday, July 29, 2006
Always name your variables well - even if you're just writing temporary hack code to try something out.


I spent several hours today (well, most of it was yesterday) tracking down a bug in some experimental vector math code of mine. It's the kind of stuff that's sensitive to real-time behavior, so you can't step through it in a debugger without ruining the numbers - scrubbing through a few MB of logs is the only way to find out what's going on.

For instance, at one point during this process, I had a couple of angle variables and was freely copying values between them. Thanks to some poor naming on my part, I was feeding radians into a segment of the calculation that expected degrees. (I later discovered that, thanks to someone else's poor namings, the part that was in degrees was wrong, and the whole darn thing should have been in radians to begin with.)

It was downhill from there.


I'll spare the long tale of woe and boredom (actually, it wasn't that bad - most of the time was spent 30 miles away at a poker game) and get to the punch line. I had two vectors, vref and vcam. They were to be adjusted via a series of rotations, producing the results av and avcam.

My final output was relying on the raw vectors, vref and vcam. The net result was bogus data getting fed down the pipeline; the visible result of that was chaotic behavior that was nearly impossible to trace to specific stimuli. In other words, the most pernicious type of bug. The type that makes a 30 minute prototyping task chew up 5 hours.



Whoops.

Comments: 2 - Leave a Comment

Link



Thursday, July 27, 2006
So I've been thinking about running for President. (Don't get your hopes up - thanks to some age discrimination in our vaunted constitution, it'll be a few years before I'm eligible.)

I've come up with a few major points for my platform so far. It's an interesting mental exercise, and I think it'd be funny as hell to actually try and campaign on this platform, just to see if I'd have more than a snowball's chance of actually scoring some votes.

Why I'm Better Than Those Other Guys
  • I refuse to align myself with a political party. It is my belief that partisan politics creates artificial polarisation and skews representation. To appease legal requirements, I will run under the Non Party.

  • I think it's stupid to withhold my opinions and views from voters on the grounds that I might trick some people into voting for me. The point of elected officials is to represent their constituents. If I piss you off, don't vote for me. I'm not going to lie to you to try and influence you into ticking a different box on election day.

  • I'm technologically savvy and have a solid grasp on how technology affects real people. This puts me ahead of pretty much every living politician in the country in terms of being able to make sensible technology-related legislation. No, it's not "a series of tubes," you dumbass. Don't talk out your base orifices if you don't know what you're on about.

  • Speaking of which, if I don't know something, I'll have the balls to say it - and seek advice from people who do know (as opposed to seeking advice from fellow rich people who used to go to the same country club). I'll also be careful not to muck around with laws and such if I don't really know what's going on and how my decisions would affect people.

  • Last but not least, I'm a regular average citizen. I have a sense of humour, I'm an actual human being, and I'm interested in supporting other people like me. Rich guys in suits who want to lobby the country out of existence can go jump in a freaking lake. Government by the people, not by the greenbacks.


What I Will Do As You President
  • Reform the entire governmental system from the ground up to eliminate partisan bias and open up all elected positions to anyone who is willing to run.

  • Replace the entire tax system from the ground up, likely based on a model similar to the proposed "Fair Tax."

  • Ban the use of private money (including corporate lobbying) for all political campaigning, and allocate a reasonable amount of tax funds to the creation and maintenance of web-based resources providing objective information about each candidate in every public office in the country. These resources would also include comprehensive documentation of issues open for legislation and public voting. All elected officials would be required to list their positions on each appropriate issue. For those not privileged with Internet access, free printed copies of relevant materials will be made available via suitable distribution methods.

  • Push for Constitutional reform limiting the power of the government to legislate areas of personal choice, including but not limited to religion, sexual orientation, marital status, selected substance use, and so on.

  • Enact strict limitations on the ability of any government or public agency to gather information on private citizens without due approval.

  • Completely redesign the public education system around teacher input, and push for equal status of alternative education choices, including private and home schooling.

  • Radically reduce the barriers to entrepreneurship and the creation and operation of small businesses.

  • Commission an extensive documentation project which removes all the mysterious legalese bullshit that fills up government paperwork (e.g. tax forms) and push for the use of plain, human-readable English so that real people have half a damn chance of figuring out what they're supposed to do without needing a lawyer.



That's just for starters; I'm sure I could come up with a few other interesting things to push for.

I plan to be elected by a history-making 96% majority. My acceptance speech is quoted below, in its entirety:

I'd like to thank you all for having the good sense to vote for me. For those of you who didn't... well, sucks to be you, and we'll see ya in four years. Now if you'll excuse me, I'm gonna go drink a lot and celebrate my crushing victory.



Vote Apoch in '08!

Comments: 9 - Leave a Comment

Link



Tuesday, July 25, 2006
So I was doing the rounds of the blogs and such that I follow regularly, and an interesting question arose. I'm really tempted to make a joke about a train of thought hitting me, or something like that, so I'd probably best shut up and get to the thought itself.


The question is deceptively simple: what makes these blog thingies so attractive? Why are they fun to read? The obvious answer, of course, is that they provide us a way to hear the opinions and musings of other people, who (in all probability) we will never meet in real life. But that inherently is nothing novel; various media have been doing that for centuries. The potency of the Internet as a communications forum is that it lets us choose who we listen to - and gives us a tremendous selection.

Consider a newspaper 20 years ago. In all but a small percentage of the larger urban areas of the country, if you didn't like the editorial slant of your local paper, you had two options: bitch about it every morning over your coffee and bagel, or stop reading the paper. The choice was pretty limited. Compare that to the almost ludicrous proliferation of blogs and other personal web outlets of that ilk.


What blogging has done for us is provide a way to pool tremendous amounts of stuff that various people are burbling. This gives us a giant puddle of burble, which we then filter to find stuff that interests us (purportedly this is done by pouring the burble into a series of tubes). Once we locate compatible burbles, we deliver them intravenously using something called an RSS feed. It's all gloriously technological and very trendy.

It may be tempting to suppose that, in this era of informational overflow, we are somehow more educated, open-minded, well-read, or sexy for having read a dozen blogs each morning. I mean, if reading one newspaper gives you X points in the well-read/open-minded/sexy game, reading a dozen blogs must be at least five times better, right? There's bound to be more diversity of opinion and subject matter. Replace "newspaper" with "television news channel" and the factor might spike as high as... well, my calculator crapped out with some error about "infinity", but we'll assume the factor is pretty high.


But is that really true? Are we actually increasing our knowledgeability? Are we genuinely broadening our horizons? Or are we actually doing ourselves a disservice by simultaneously narrowing our views and convincing ourselves that we're doing just the opposite?

Try a quick thought experiment. Suppose you're surfing, say, Reddit, and find a link to Foo's Blog and Grill. It's got a high score, so it must be pretty good, right? You click over to Foo's and start reading. The first entry strikes you a bit odd, but hey, everyone has off days, and this was ranked #5 on Reddit, so it must be good. The second entry is no improvement. By the fifth entry in the archives, you're totally offended - not just offended, but genuinely pissed, and you've already dug out your knife collection and sharpened half of them before you realize that you have no way to find out where Foo lives.

So, do you: (A) bookmark Foo's Bar and Grill as an outlet for conflicting opinions with your own, and a remarkably good way to expand your views on the world, or (B) close the site, rate it down on Reddit, and flame the shit out of everyone you can find who does not express extreme loathing for Foo?


If you're like me, your tendency is more towards (B) than (A). (Actually, if you're like me, you don't even get that far - you realize that you're a programmer, dammit, and you can find out where Foo lives. When you return from brutally murdering Foo three days later, you discover that the power went out while you were away. After rebooting, Foo's site is of course no longer displayed on your machine, and you promptly forget about it forever. But then again, I'm pretty screwed up, so I don't really expect you to be like me. I'd be flattered if you were, though.)


What does this reveal about us? Actually, it mostly just reveals that people are self-absorbed scum and prefer hearing things we agree with. That's not news, at least not to certified members of the Pessimistic Cynics Society. What's more interesting is the intellectual dishonesty.

Now, I'm going to go out on a limb here and just invent some stuff. I don't know this for sure, but it came to mind, and it seems plausible. More importantly, it makes for good reading, even though it's total fictional crap. So take it how you will. That said, I theorize that most (if not pretty much all) people spend at least part of their blog-reading time convinced that they're expanding their horizons, when in fact chances are they're doing the opposite.

What's more enjoyable, reading a blog full of stuff that sounds like ignorant drivel, or reading a blog from someone who has made themself appear to be very respectable, and finding (amazingly!) that you agree about all kinds of stuff? Aside from the occasional fun of flaming people who are clearly morons, I think it's far more rewarding on a fundamental level to experience the latter. Most successful bloggers have done a great job of overinflating themselves, and convincing people that they're important and have lots of important things to say. After all, that's why we snagged their RSS feed. So if you're reading Joe's blog, and you really respect Joe because he's just this incredibly awesome, smart, and good-looking guy, aren't you going to feel good when you discover that Joe happens to agree with your opinion?

It's a shot of happy-juice for the ego. In fact, it's an age-old human tradition. It comes in many forms, most of which are considered reprehensible by society, but pretty much everyone does it to some degree. It's nothing more or less than the same psychological reward of being a suckup.


When we agree with someone who we perceive to be respectable and/or influential, it earns us all kinds of points. We feel good about ourselves - it's the well-known confirmation bias. We look good to other people, too. Since human beings are mind-bendingly lazy, we find it much more convenient to form our opinions of people based on how closely they fit some ideal of ours, rather than actually basing our opinions on the person's real merits. This all happens in reverse, too: if we find out that someone agrees with some other person who we revile, our opinion of that first person drops a few notches. You know you've done it.



That's why I personally am a little scared of the Internet. I think it's stealing our brains. We talk about it as if it's going to liberate us from the overly biased, money-centric media of the 20th century. It'll set us free from those right-wing lunatics over at Fox News (see, lookit - I just earned points with a bunch of people). It'll finally cure the problem of being unable to connect with other people's views. The Internet will make war and conflict obsolete, because everyone can find out about the issue from many varying sides, and reach a mutually tolerable conclusion - or, at the very least, start an edit fight on Wikipedia.

Somehow, I don't think it'll play out that way. The urge of human beings to seek out information that agrees with pre-determined views is simply too powerful. Moreover, that tendency doesn't get nearly the respect it should from people who think they're being objective. To make it all worse, the Internet lets us deftly convince ourselves that we are being objective, when really all we're doing is making our confirmation bias more efficient - and more powerful, since we can feed it from the vast stores of agreeing information on Google.


The Internet is the new statistics - you can make it say anything you want. It is my personal fear that the Internet will not lead to a massively cooperative utopian society, but rather the opposite. People will polarize and congeal into cliques based on their predetermined ideas and opinions, and form increasingly segregated communities. Isolationism and bias will become increasingly potent. We've already seen the classic signs of feuds and turf wars from various online communities - hell, some of them started before "Internet" became a household word.


The next 20 years should lead to some interesting cultural problems. If you thought the raised-by-TV generation was messed up, you ain't seen nothing yet. The raised-by-Digg generation is coming.

Fear.

Comments: 8 - Leave a Comment

Link



Friday, July 21, 2006
Being technically inclined is a bloody curse. Sure, there's the usual nightmare of relatives asking us to discard our holidays to "fix my slow computer" and such inanity. But that's tolerable, for the most part. Usually it's either so simple that you can earn a few extra brownie points and only miss 10 minutes of not-working, or complicated enough that you can gasp, stare at it wide-eyed, and proclaim with absolute certainty that you have no idea where to even begin.

The real killer comes after you've done something impressive in front of someone non-technical. Usually, this involves little trivial leaps of deductive reasoning that make utter sense to anyone technically inclined. We can see that it was a pretty simple conclusion, and that the result was borne out of a solid understanding of the systems involved. In most cases, it's so simple that we totally take it for granted.

But the evil truth is that the non-technical audience does not share our understanding of how simple it really was. All they see is that we have apparently done magic, and we made it look easy. They don't have the first clue what we're doing, so to them, what we've done is utterly inscrutable voodoo. We must have some kind of glorious mystical powers.


That's really not so bad, in itself - and in some cases it can be a nice booster for the ego. The problem is that it creates a false conception in the minds of the non-technical. They assume that because we have once done something which (to them) was utter magic, that any time there is some technical situation they don't understand, we can solve that, too.


Suppose a humble businessman (perhaps the proprietor of a pie shop) finds himself trapped in a subspace vortex, or some such pseudoscientific rubbish, and is teleported in his car back to the stone age. He finds himself surrounded by hungry cavemen who are eager to devour this new stranger. So he turns the keys, starts his car, and drives away from the lunatics, and reaches safety.

See, to modern people, that's pretty obvious - guy just drove his car. Big fricken deal. But to the cavemen, there has just been a whole lot of magic going on. So they hunt down the guy and make him a god - that's the good news. The bad news is, a pack of sabre-toothed tigers is about to eat everyone in the village. Counting eagerly on their newfound god for salvation, the cavemen thrust the pie-dude forward to greet the carnivores.


That's what happens when technical people work among non-technical people. I don't meant to insult or offend anyone by comparing them to cavemen, but that's really how drastic the separation is.


Suppose a programmer (let's call him Joe) gets handed some task with a set of crazy, disparate, and vague requirements. He quickly spots a common thread based on his understanding of the problem domain, finds a more generalized and elegant solution that the one requested, and manages to impress everyone; his version does precisely what is needed, and more, in less time than expected. It's a great solution. For a few weeks, he's the new god of the tribe.

Fast forward to the tiger attack, a.k.a. the next project. Someone comes up with this really big, scary thing that needs to get done. Remembering the last incident, they find Joe Programmer, and throw the project in his lap.

To the non-technical, it makes sense. Last time, they had a big scary problem that nobody understood, and Joe solved it. This problem is big, it's scary, and nobody understands it... that's right up Joe's alley!


The problem is, Joe doesn't understand it, either. The fact that he understood the first one so well was just random luck. Desperately, Joe tries to find clarity - better specifications, user stories, use cases, anything and everything he can get ahold of to help understand what it is he's supposed to be doing.

The pie-salesman stands before the crowd of cavemen, trying frantically to make them understand English, so he can ask them what the hell he's supposed to do about all the ravenous tigers coming his way. The cavemen hear pie-man's frantic yells, and interpret them as magical incantations. They watch him dance about in panic, and for all they know, he's doing a rain dance. When he runs to them, pleading for his life, they smile and shove him back towards the tigers, confident that he will save them all with his god powers.

Joe never does get his specifications. The users insist that he just "go do what we need" and never do provide any information. Frantic, Joe tries to study up on the problem domain on the Internet and his local dead-tree library; he barely scrapes together a half-functioning prototype, but the users give him odd looks and ask why he's wasting time instead of finishing what they wanted to see.

The deadline comes and goes, and Joe fails to deliver. The entire product is now at risk. A few weeks later, still with no sign of the magic deliverance they expect, the users become disgusted and leave. As clients abandon the product in droves, the department comes under intense scrutiny from upper management. Following a dismal quarter of record losses, the brass decides it's time to cut the fat, and dozens are laid off, including Joe's manager. Joe himself is spared, since people vaguely remember him as being some kind of hero; there is some controversy, since it seems pretty well agreed that he's responsible for all this mess (after all, it was his slippage that started it all), but he has enough supporters to survive.

Upon receiving the memo, Joe's manager despairs. He is found later that day in his office, having shot himself in the head. Two other employees of the department leap off the roof of the headquarters building later that week; one is paralyzed from the waist down, and the other dies before arriving at the hospital. In the ensuing investigations, dark secrets about various highly-placed members of the company come to light, and a series of scandals tears apart the upper echelon.


Eventually, the company files for bankruptcy protection, and lays off all but a few "mission critical" employees. Joe is among them, having since redeemed himself on a few projects when it really counted.

The company is finally close to posting its first profitable quarter in almost three years. They are hailed as the potential comeback story of the decade in such prestigious publications as Fortune and Forbes. To pull it off, they need only to deliver one final product to a particularly sticky client.

Joe is summoned for his magical programming wizard-abilities. After a four hour meeting with the client, he has no idea what he is supposed to be working on, how to accomplish it, or even what the client thinks the product is for.

On his way home, Joe is deeply depressed. Memories of his past experiences haunt him and torment him. Finally, unable to cope with the pressure, he leaps off the subway platform and is killed instantly by an arriving train.



In the aftermath of Joe's loss, the tigers surge forward into the throng of cavemen, who gathered to watch Joe deliver them from their doom. Shocked and confused, the crowd is rooted to the spot - not a single person runs. A few still smile as the tigers topple them to the ground; they still believe that the pie-man's death is just a ruse, a diversion. Their newfound god will rescue them all.


In a few short minutes, it is over. The CEO writes a hot check to try and buy airfare out of the country, but is arrested for fraud before he can board the plane. Within a week, the doors of the once-great software giant have permanently closed.

The heaping mound of slaughtered corpses rots slowly in the sun; and none live to tell the tale of what befell them.

Comments: 3 - Leave a Comment

Link


You win some, you lose some.


On the plus side, I was able to hold to my position and refuse the extra job. That wasn't too bad.

On the negative side, the original "short" task I contracted for ended up ballooning into a slightly more involved list than I would have liked, so I haven't technically fulfilled that yet. (You'd think one of these days I'd learn to get specific limits put into writing so I'd quit getting suckered by that; heck, it was one of the primary reasons I decided to quit freelancing.) So I'll have to go back in sometime in the next couple of weeks and finish it up.

Thankfully though I made it clear what my situation was, so I'll basically get to decide when I go back in to finish things.



In the meantime... I'm committing this weekend to taking off entirely with no work, again. If I find the energy to work on stuff like Epoch, I'll definitely go for it, but chances are I'll be doing a lot of sleeping and gaming instead - I've got a lot of non-work to catch up on

Comments: 0 - Leave a Comment

Link



Wednesday, July 19, 2006
Life is just too darn short.


I think, at some point or another, pretty much everyone realizes that. Sometimes it's fairly early on. Other times, it's late in life - maybe even painfully late. It's certainly no new, deep, meaningful insight. Plato has not rolled over in his tomb.

It may not be news, but it sure is easy to forget. We may forget for any number of reasons. Young people getting their first taste of independence and life feel like they've got forever - those ancient fogeys in their late 20's are old, man. College graduates dive into the wide world of career employment, and look forward to the endless expanse of time they have to make their mark on the world. Then the 30's happen, and the weight of "being old" starts to hit in force. But that doesn't last long; the people who really are old quickly remind us that we've still got plenty of time.

And we go right on having plenty of time, until the late 40's or so, when everything turns into a slog. We count down towards retirement, and look forward to finally breaking free of the chains of corporate life and moving on to enjoy our declining years. Once we hit retirement, we get one more sweet taste of having all the time in the world.

From the looks of things, we tend to enjoy that for a couple of years, and then the utter boredom of being retired sets in. We struggle for a bit, take a couple of cruises, and then resign ourselves to playing golf until we're packed up in an afghan and sent to the rest home. And now, for the last time, we have all the time we could want - probably too much time, because it's so damn boring sitting in this chair and napping all day.


Sometimes, in the midst of having all that time, we get sharp reminders of just how little time we really have. Human history is piddlingly short, and yet it's so huge that any one person's slice of the timeline is just a few stray droplets of paint on the canvas. Human life is, despite all our technological faffing about, shockingly fragile. Sometimes it takes a pretty big jolt to remind us of that.


Maybe being aware of it is too overwhelming to sustain, and we supress the knowledge so we can enjoy the time we do have. Maybe that's why we have to be reminded sometimes. Maybe that's why those reminders are so impactful on our lives.



Fortunately, sometimes our subconscious decides to pull its fingers out of its ears and quit singing loudly, just long enough to remind us of that all-important fact. Sometimes we even get lucky enough for that reminder to come just when we really need it.

The last couple of days have been a bit tough for me. Yesterday, I went in to my old job for what I thought was a short contract - something on the order of a few hours. I was just going to duck in, help them get some bugs fixed, collect my check, and be on my way. It was just a little gesture of courtesy to help them out while they continue to try to find a replacement to take over my position there.

I was in for a pretty major surprise. Apparently things have been going quite well lately, and a lot of clients are expressing a lot of interest - i.e. there's some hefty mounds of cash at stake. The catch is, most of them are interested on the condition that the company's product be tailored slightly to suit each individual client's needs. Lacking a full-time programmer, the company simply isn't capable of doing those customizations at a reasonable pace.

The upshot is that I was basically offered my old job back. Or maybe just part time. Or twice a month. Or whatever. There would be a very, very substantial increase in compensation involved. I would have complete and utter control of when I worked, how long I worked, even where I worked. In short, they'd addressed basically every single issue I had with the job in the first place. They didn't just fix the issues, they blasted them into oblivion. Then they rebuilt them, molecule by molecule, and blasted them again, just to be spiteful.


In case it isn't clear, the offer was very, very tempting. I wasn't really ever interested in going back full-time; I enjoy game development far too much for that (not to mention the unfairness of pulling out on Egosoft after spending three years telling them I wanted to work there). But I did think about a part-time arrangement... after all, how bad could a day or two a week be, right?

I spent the rest of the day there, working on what I'd originally come to do. I got back into playing with some of the technology they have there, and got to work on diagnosing and fixing some problems that were quite different from the kind of fiddly little crap I squandered my weekend working on. I had lunch with a couple of friends of mine from the company who, for geographical reasons, I virtually never see anymore. We reinstated the old tradition of throwing random objects at each other over the cubicle walls - bonus points for getting the other guy to chuckle or yelp during a phone call.

After the draining experience of last week - especially Saturday - I was dangerously close to burnout. I knew it. I've burned out before, badly, and I know the warning signs. I take it seriously enough that I deliberately did almost nothing but play games and read all day Monday, just to get away from work for a bit and recharge. It costs less to spend a day not-working than it does to burn out and spend weeks doing subpar and half-hearted work.

By Tuesday, though, I still wasn't entirely over the burnt feeling. It was such a refreshing change of pace to work on something totally different that, for a few short hours, I convinced myself I really wanted to work on something totally different. I thought maybe I wanted it enough that I'd take up a part-time position again, just to get some variety, and to get a bit of the social interaction that is (sadly) pretty lacking in my current job situation.


I spent all of Tuesday night and pretty much all of today agonizing over the decision, trying to figure out what I really wanted to do, and come to terms with my situation. Towards the late end of today, I made a few realizations that really clarified things.

For one, I'm still not un-burnt yet. I haven't totally recharged, and although I need to do a few things just to stay on top of my obligations, going back into things full-bore at this point would be a mistake. I've already committed to going back in to the other job for tomorrow to wrap a few things up; that break will be important, and I'll probably keep the rest of the week light as well.

The other thing that really struck me was how devious burnout can be. Last fall, in the aftermath of the X3 project, I was so utterly burnt out that I did very little for three months besides stumble in to work, and then crawl home and sleep. In the process of recovering from that, I swore that I would never again take on two full-time jobs, especially not with one of them being a game in the middle of a highly time-critical crunch period. The burnout was so severe because I never really felt close to burning out; switching between two totally different jobs was enough to keep things feeling fresh, even while I "inexplicably" became increasingly drained of energy and motivation. It wasn't until well after the fact that I recognized it for a genuine burnout, and not merely routine tiredness.

Lately I've really had some problems balancing time spent on work, and time spent on everything else, like life. I realized that I really don't have a good sense for when I've done "enough work" - for some dumb reason I tend to feel obligated (or something) to do as much work as I can until I can't do any more. That's a hand-crafted recipe for burnout. To make matters worse, I've lately found quite a few interests that I'd like to pursue, but don't feel like I have the time.


And then it all finally clicked, and I realized how close I was to making a bad mistake. One of my big reasons for taking this job was the flexibility in schedule - namely, that I would finally have the time to pursue all those other things. Yeah, there's a lot of work to be done, but it'll still be there tomorrow - if I don't have time to do things outside of work, it's my own damn fault.

Surprisingly, it was really hard to see (for a while) just how much worse I would have made things had I gone ahead with taking back on a second job. Sure, it would be part-time... and I'd have total control over it... but I know that eventually that wouldn't be enough. I tend to be an obsessive perfectionist in my work, and I know that no matter how much I denied it yesterday, eventually I'd give in to the temptation to (effectively) be doing two full-time jobs again. What's worse, I probably wouldn't have realized I was even doing it until it was far too late.

At that point, the burnout would have been devastating. In all honesty and seriousness, it probably would have been the end of my career in software. And I don't want that.



So tomorrow I'm going to go in one last time, finish what I came for, collect my check, and move on. Life is just too darn short.

Comments: 2 - Leave a Comment

Link



Sunday, July 16, 2006
Persuant to my goal of not working this weekend, I decided to fire up my recently-upgraded gaming rig and install the copy of Tomb Raider: Legend that came bundled with the GT7900.

It didn't quite work as planned. In fact, I think some of the lingering effects of yesterday oozed through the space-time continuey-thingy and screwed up today, too.


There really isn't an interesting story here; suffice it to say I spent several hours trying to figure out why the game crashed as soon as the main menu loaded, and finally tracked it down to DEP after reading probably a hundred tech support threads. It was a tedious and thoroughly unpleasant process.

Of course, DEP wouldn't have been doing nuts if the game wasn't loaded with a crap copy protection system... but them's the times we live in.


Once I got the game running, I found it quite enjoyable; the controls are very easy to use, although some of the directions get confusing when the camera gets all twisted at weird angles. I suppose it's primarily my lack of third-person game experience (since the first Tomb Raider, in fact), and I've already gotten accustomed to a lot of the quirks.

So far it's a great-looking game, and the story is at least interesting enough to move the action forwards. I'm only about 1.5 levels in, since all the troubleshooting crap gave me a raging headache and I didn't feel like playing for long.



In the middle of the troubleshooting mess, I dug out my install of Enemy Territory and played a few maps on some random server. I haven't played ET in years, and the last time I tried to play I couldn't find a single server - they were all crap mods full of ignorant kids who didn't understand the game and had no strategy. I've been out of the scene for far too long to get into clan play, since all the clans that still play are pretty hardcore. So I figured ET was dead.

Apparently, though, something interesting happened in the past 18 months (or whatever it's been). Nowadays, most servers are sparse, and given the fact that the first server I tried ended up being quite pleasant, I suppose that means that the only players out there are the people who are really interested in playing the game legitimately. So I'll probably play quite a bit of that again now.


Anyways... headache, and bleh, and such. I think I'll take tomorrow off, too, so I'll get a proper two consecutive days of not-working.

Comments: 0 - Leave a Comment

Link



Saturday, July 15, 2006
I'm on the verge of screaming.

Either that, or breaking down and weeping in a high-pitched wail until I drown in a pool of my own tears. I'm still trying to decide.


The last couple of days have been a nightmarish marathon of convoluted debugging work. It started yesterday, at some early hour, I can't recall when. (Things have literally been so crazy that I don't know when I've been awake, when I've been asleep, or anything. I just remember a long blur and my butt getting really sore from sitting so long.)

The first bug was with some modifications to some XML loading code. There was a node in the XML tree that had been loading since Day One and working great. I needed to add a couple of subnodes to it for a new feature. Things seemed to work fine; my ad-hoc unit tests showed that everything was running great, provided the XML was loaded correctly.

Naturally, the XML wasn't loaded correctly.

I spent hours poking around and rearranging code, trying to find where the load was going wrong. I finally convinced myself that the loader was indeed to blame, but I was staring right at the code - there was clearly a loop that iterated through each subnode and loaded it.

I output the number of subnodes before running the loop; the count was correct. I manually output the entire subnode tree fragment to convince myself it was loading. Then, in desperation, I added a simple line to the loop that would write a log entry each time the loop iterated.

It only ran once.

This prompted me to jump about my apartment in a furious rage, shouting obsenities like Samuel L. Jackson himself, and pounding on various household objects with a soft rag (even in my psychotic outburts I try not to break stuff if I can avoid it). After doing my impression of a gorilla that just got shot in the ass for a few minutes, I sat down again, ready to tear the loop apart and totally rewrite it - some crazy evil voodoo was breaking the laws of physics. I mean, the loop constraints clearly said to loop through each subnode - that worked fine (I even made a separate dummy loop with those constraints just to convince myself they worked). The subnode loading code worked. The function wasn't being aborted early. It was almost as if the loop was being explicitly aborted after the first iteration.

... and then I found it. For some unfathomably moronic reason, I had a break; line at the end of the loop, hidden out of sight between a couple of closing brackets, just lurking in the shadows, waiting until it could lunge out and slice off the ankles of passerby.

I honestly can't tell you how stupid I felt. I meekly ripped out all my debug logging (the more recent of which was littered with rude remarks about the nature of deterministic computing machines) and checked in the bug fix - one whole line of code removed.


Damnit.



As if that weren't bad enough, today had to happen. I originally wasn't going to work at all this weekend - just play some games, go run around in the Big Blue Room a bit, and catch up on some reading. The old fashioned kind of reading, with the little analog thingies - you know, that have all the ink and slices of dead trees and stuff. It was going to be a good weekend. It was going to be the way weekends should be, which is to say, not full of work.

I woke up last night around 10 PM, thanks to my body's utter lack of a functioning circadian rhythm machine (I think it has a QPC dualcore bug and I haven't updated the drivers yet). I waffled around for a bit until around 5 AM, trying to force myself into not working. Unfortunately, I'm a bit obsessive, and I'm also a day or two behind on my estimated progress - largely due to stupid bugs, which I won't mention.

Oh wait, I already told you about that. Anyways.


So finally about 5, I convinced myself to tackle this next feature. It's no big deal, you know, just tweak a couple things, refactor a few functions, and wham - all set. Nothing to it. I had complete plans for the changes written out on my notepad, with every single step needed to implement and test the additions. Foolproof.

It went smoothly for a while, until I got to the last bullet point on the list. Up until now, this system has only understood statically timed sequences of events - the XML tells it when every single operation starts, and when it stops. When the XML is loaded, a lot of relative timing offsets are converted into absolute time, and condensed into a "playback operations list," which is basically just a queue of "start this process, stop that process" commands and a timestamp of when they are to be executed.

The plan for this morning was to add the ability for commands to be triggered dynamically from code, rather than have statically defined timings. This was broken into two parts: starting events dynamically, and running a started process until an event occurs, and then shutting it down.


Around 8 AM, I had the first half totally working - it was tested out fully and running beautifully. Not a hitch. So, being an idiot, I told myself that I could get the second bit done in maybe an hour or so, and then go watch THX1138 and get on with all the relaxing and not-working I was planning on.

Around 1 PM, the debugging had become so frustrating that I came over here to write up my tale of woe, hoping that in the process of explaining my predicament I might figure out what I had overlooked.


What I had discovered was truly bizarre. An operation with a dynamic duration would never get started. It would load from disk correctly, and when the start event was raised, the commands to start the operation would be inserted into the playback op list correctly. They would even be popped off the queue and executed correctly. The entire command to start the operation worked flawlessly - no problems, no errors, all the expected values spewed out into the debug logs.

Except that, unlike every other op-start command, this one had no effect. Nothing would appear on the screen. A few seconds later, the op-stop command would be triggered, the process would be terminated, and everything would clean up. There were no errors to indicate that the start had failed - the shutdown was clean, and produced output that indicated that the operation had indeed been running in the background. Except nothing ever showed on the screen.


My attempt to articulate the story of the bug almost worked, except that just when I was getting to the good stuff, I got distracted. My stupid pea-brain decided that it wanted to figure out what random keystrokes did - in my browser window with the half-written entry.

One of the combinations I happened to press was Ctrl+W.



DAMNIT.


I was too drained to even be mad - after all the frustration of the morning and the last couple of days, I was just depressed. Heavy of heart and despairing for my life (well, ok, just despairing for my weekend) I turned back to my IDE and began to poke things again.

I double-checked everything for the command, running it over in my mind, and trying to see exactly what possible flow of logic could cause what I was seeing. There just was no way - by all measurable signs, the process was running.

But how could it have been running if it didn't draw anything onto the screen?


I was close to giving up and just spazzing out again, when I happened to scroll past a function that I wrote ages ago, and long since signed off as working correctly. Something about it niggled at the back of my subconscious, so I checked it over - hadn't been changed, and still passed all the tests. Nothing wrong with it.

Then I stopped and thought about what precisely it was doing. Due to the structure of the data, there is precisely one case where a node in the tree doesn't handle all of its own operations - one operation is handled by the parent node, and propagated down to the child node.

That couldn't have been the bug, though, because it was passing tests! No way was that function at fault.


But what if it was?


I checked over quickly what would happen if something went wrong - say, for instance, if it failed to find a child node and propagate the data. The net effect, in that impossible and totally not-happening case, was that the clipping region for the node would be set to a 0 pixels square.

In other words, if that particular function failed to find a child node, it would have the net effect that the child node would run perfectly as expected - with the sole exception that it would show nothing on the screen.


DAMNIT!


I checked up on the function that searched for the child node, and sure enough, there it was - a tiny little assumption that the child nodes would all be statically timed. Removing that assumption was a two line change.


(And, as if to celebrate the happy news, one of my favorite songs - Sleep by Conjure One - just started playing on DI. Woohoo!)


A quick compile and test seems to indicate that I've nailed the little rat bastard - except I can't tell for sure. Somewhere along the line, out of desperation, I commented out the ability to stop processes from running, on the off-chance that the dynamic process was getting killed before it could display anything. So now I have two processes trying to draw their output into the same rectangle, and all I get is chaos. D'oh.


This is where things get truly agonizing - I think I've nailed it, but I don't know. It should just be a quick recompile and retest to find out for sure. Except when I say "quick" I mean "butt-ass freaking slower than frozen molassess running uphill on the surface of a neutron star." Or, in slightly more clear terms, "not quick."

A compile can take between 30 seconds and 2 minutes, depending on what got affected. Launching the game and getting it to a point where I can run the test takes about 3-4 minutes. After all that, I can run the actual test, which takes 15 seconds. And due to data dependencies in the sytem I'm working on, I can't split it out into a separate app/testing framework to get it all developed.

This is the main reason why I'm looking forward to a new development machine so much - anything to reduce the perceived slowness and torment of the compile/debug/run cycle. It's enough to make me wish we were using Lisp or Haskell or something so I wouldn't have to recompile and restart and all.


So... with everything restored (I hope) to its correct logic, I set up one more run. I'm stupid enough to hope this one will be the last, but cynical enough to expect that it won't be.


Boy, can I call 'em or what? This time, everything runs correctly, and the dynamic process starts as expected. It even stays running! ... and running... and stays running. Either the command to stop it isn't being obeyed, or the event that triggers the stop command isn't being thrown correctly. According to the debug logs, the event isn't firing.

Now I have to trace the call upwards a layer, to see why it isn't being fired from the client code. It looks like there's a data screwup in the raw scripts, and unfortunately the guy who understands those scripts (and the code that runs them) is off not-working today. He's most likely doing exactly what I was supposed to be doing today... bastard

Thankfully, after a little bit of thought, I figured out my own mistake. A short tweak to the data, removal of some debug logging and small hackery, and we're off for (yet another) test run. Bizarrely, this new test data is churning out a lot of bogus negative numbers in weird places.


WILL IT NEVER END?!?


It takes quite a bit more time to straighten out a series of stupid typos and brainless mistakes in the test data. Finally, I reach a nasty inversion of my earlier problem: dynamic-length processes won't stop. The event fires, the operations to stop the process are queued and executed... and the bugger just keeps on running.

Finally, the guy who knows the scripts shows up online, and we hash out the problem and a working fix. There were actually two or three little things all going wrong at the same time, which led to the bogus behavior.


At long last, everything is debugged, and running as intended. The last scraps of temporary debug spam are snipped out, and it's time for one final test run to reassure myself that it hasn't spontaneously decided to break again in the meantime.


For a pleasant change of pace, it works flawlessly.



So here it is, 4PM. I've just finished a marathon of close to 11 hours of work I swore (on things very... precious to me, like my Yoda plushy collection, which I only own in my imagination) that I would not do today. Crap.

This story - and indeed pretty much all of this past 24 hours - has dragged on more than I really care to think about. I was planning on going off and cashing in on my hard-earned relaxation, but it seems the universe just isn't done taking a piss all over me yet.


Now there's a huge thunderstorm kicking up, and it looks like my gaming-slash-catharsis session is about to be killed before it begins.


Now I'm going to go cry.

Comments: 5 - Leave a Comment

Link



Friday, July 14, 2006
Every now and then there's a lot of waffle about innovation in UI technology, extending or replacing the metaphors we use to interact with computers, blah blah. Usually this centers around some abstract 3D file browser or some kind of cheesy and thin analogy that conjures up unwanted memories of Microsoft Bob.


Today though I found something that not only managed to impress me, but make me actually want the technolog. Via the Joel Reddit, here's "Creative Mess on your Desktop".

I actually laughed out loud a couple of times during the video segment - it's that cool. It's pretty much precisely how I envision my dream-desktop working; in boring old real life, I "stack" icons into little piles all over the place and generally make a lot of marginally organized chaos - just like my real desk. This tech takes physics simulation and abstract UI tools to bring the metaphor one step closer to life - hell, it's even better than life: when was the last time you pointed at a pile of documents on your desk, said "sort by type," and had them all break into neat little piles aligned on a regular grid? Didn't think so.


For all the hype around "radical" and "innovative" UI technology, I personally usually find it a waste of time; the tried-and-true stuff is good enough to keep using, and often the benefits of the "new" tech are marginal at best. This, though, looks like it has some genuine potential to enhance the way we use our computers - and you don't have to be Tom Cruise in the year 2649 to use it, either.

Comments: 2 - Leave a Comment

Link


The last couple of days have been pretty tough, hardware-wise. I bit the bullet and rigged up my shiny new 7900GT in my gaming machine (and fixed the northbridge cooling) over a week ago now, but I haven't had the heart to play much with it. Meanwhile, I'm still hobbling along on my old development box, and it's starting to be agonizing. Every little millisecond delay adds that much more frustration and annoyance - as a matter of fact, that was a large inspiration for yesterday's tome.

My original plan was to build a new dual-core development machine, based on my very pleasant experience with my new dual-core laptop. Someone pointed out the imminent Core 2 Duo launch from Intel, and a corresponding rumour that AMD would slash prices on their processors to try and avoid taking a massive beating. I'm still not sure whether or not I'm thankful for that tip, as it's caused me a lot of suffering - delayed enjoyment of New Hardware Goodies is very hard to cope with.


Now, though, things are getting really interesting. With the NDAs on Core 2 Duo lifted, we're starting to see some of the first solid benchmarks of the new lineup - and it is absolutely, uncontestably clear that AMD has been spanked. Bitchslapped. Pwned, to adopt the popular parlance of the community.

Of course, there have been hints of that for weeks now; however, up until now, a vital piece of the puzzle was missing: launch pricing. Let me tell you, folks, the launch pricing is just plain and simple orgasmic. There is no other word to capture it.

To put it in a nutshell: take the top-end FX processor from AMD. Yeah, the ones that cost like $950 a shot. Now imagine a processor that's a good 20% faster, with half the power consumption. That processor costs $320.


This is a hard thing for me to take; for quite a while now I've been building AMD machines exclusively. In fact, the laptop is the first Intel machine I've owned in close to 5 years. It has nothing to do with company loyalty, mind you; I'm a total whore, and I'll jump ship in a heartbeat for whoever has the best value available. The shocker is that not only has Intel started actually offering good value again, it's actually incomparable with AMD. There simply isn't any contest. Considering how laughably inferior the Pentium 4 architecture has been in practice (especially compared with the hype it received in the early days), I'm just plain floored at this comeback.

But of course the decision gets sticky. I'm more or less settled on the E6600 ($320 MSRP, probably run $300 street on places like NewEgg) as it hits the sweet spot of value-for-money as far as I'm concerned. However, the problem is that motherboard lineups are currently a bit iffy. Not all LGP775 motherboards will cope with the Core 2 Duo's features, and I'm not going to take the dive on being an early adopter if I can't even adopt half the goodness I'm paying for. This means I'll probably need to wait for motherboard announcements - and that means a price wildcard.

There is hope, though; for several years now, high-end motherboards for brand-new CPU lines tend to run between $180 and $220 around launch time. So based on this estimate, plus the cost of the CPU itself, I can roughly guage what it would cost to go Conroe vs. going Athlon X2.


Bottom line is that I could go X2 now and get a decent stack of hardware for $550, between the motherboard and CPU; a slightly less extravagant motherboard drops that to $500. If I wait for a couple more weeks (aaacckk) for the supposed price slashing, I can probably cut that down to $380 or $400. That is far from certain, however.

On the flip side, I can wait three more weeks (graaaagghhhh!! urghk!) and go with a hot-off-the-lines E6600, and matching motherboard. Based on my estimates, that'll drain me for roughly $500. If a decent value motherboard becomes available (quite likely, since a high-end mobo isn't really necessary for me) I might get away with... $400 or so.


In other words, I can opt for immediate gratification, scratch my hardware-lust itch, and land myself a reasonably performant CPU and motherboard. After waiting for shipping, I could be writing code on it in a week's time. Or, I can hold out another month, and for the same amount of money, get a machine that absolutely shatters what the AMD box possibly could have offered. Plus, I get an extra month to collect interest on my savings, which means I (sort of) save a tiny bit extra cash.

It hurts to think about hobbling along on this old crusty box for another month, but after all the railing I did against the gimme-now attitude yesterday, I'll probably have to suck it up and just wait. At least that wait will be very much worth it

Comments: 4 - Leave a Comment

Link



Thursday, July 13, 2006
I have a lot of fun hanging around here, especially the For Beginners forum. Watching people develop their skills and progress to bigger and better projects is fascinating for me, and it's always fun to see what dedicated and hard-working people can create.

It also reminds me of my own early days, of creating "games" on a little Sharp Pocket Computer in some unholy dialect of BASIC. I remember the first time I sat down with a full copy of QBASIC on my parents' laptop and started to experiment; one of my first goals was to create a clone of Commander Keen (and fix what I perceived to be some severe design issues in the game, namely that I sucked at it and couldn't beat it). For years my secret dream was to get a job making games, although I rarely admitted it, because for some reason most people don't take that as a serious career choice - apparently I was supposed to do something "useful" with my life.

But now here I am, and oddly enough people take my career a lot more seriously these days. I guess game development has a much better reputation now (as a "real" business) than it did back in the early 90's - which is fair, I guess, considering most of those "businesses" were run out of garages and sold product in plastic bags.


In a lot of ways, things are pretty much as I expected: I sit around eating junk food and writing code most of the day, have a pile of top-end hardware sitting around, and get to go to events like E3. What strikes me most, though, is how different the reality is from what I would have expected - and, from my time here, it seems that those misconceptions are more or less ubiquitous.

For instance, I always figured I would work in a cubicle, wear a coat and tie, and report directly to a "Manager" who I called "Mr. Boss Sir" all the time. I suspect that that particular misconception was more the result of my ten year old brain trying to comprehend the life of a working man, but I still think it's funny how totally different my job turned out to be: I work at home in my apartment, wear jeans and a t-shirt (except for Pantsless Thursdays), and our team has an extremely flat hierarchy. Go figure.


One thing that turned out to be correct has also turned out to serve me very, very well over the years, both in the game industry, and as a freelance contractor before that. I have always considered it the chief responsibility of an employee - and, more importantly, of a team member in general - to contribute all of his skills and abilities to the ongoing good of the team effort. I suspect I got this largely from my father, who has always been admirably philanthropic, but in any case it seems to be fairly rare, especially among the current high-school generation that's preparing to start looking for jobs in the next few years.

To be honest it worries me a little bit, but that's probably just because I'm a cynical pessimist bastard and I worry about everything. Regardless, I see an awful lot of people - especially in this community - who approach things from the opposite perspective. People seem to expect that they are entitled to everything, and that the world exists to serve them. This is really a symptom of a larger cultural phenomenon I think, and it by no means is limited to the young people of today. I'm not educated enough about cultural history to speculate on how this situation came to be, but it most certainly came to be, and now we have to deal with it.

Many people begin their game development experience with this sort of grandiose vision of being some kind of "lead," with dozens of people at their beck and call to carry out their every gaming whim. The most extreme case of this is people who don't want to master any particular skills - they just want to be the "idea guy" who tells everyone else what to make. The more of these people I see, the more I suspect that such thinking arises from the entitlement attitude.

These people seem to believe that they will be in positions of power, where their underlings/headcount/demeaning-term-of-the-weak exists solely to do what they want. This kind of power-hungry drive manifests in many places outside of just the "idea guy" crowd. In fact, it is often most dangerous in places like programming, where a single control-obsessed person can wreak havoc on a code base and create all manner of headaches.

The common mental image of the "lead" or "manager" or "boss" is the command-and-control drill sergeant who fires off orders in a loud voice and probably smokes a lot of cigars. Sadly, this stereotype actually occurs in the real world (albeit a little bit less caricatured) because at one time command-and-control was considered the ultimate method of management. So this vision of the "Boss Man" who wields the combined power of dozens of his underlings is particularly entrenched, especially in American culture.


What's interesting is that pretty much everything written these days about how to manage and lead teams in the IT world goes totally against this. Good leadership isn't about yelling orders and building layers of bureaucracy. Leaders don't sit at the desk and yell at everyone to charge forward. Just look at the etymology of the word itself: a leader should be someone who leads. That means going out in front.

A few years ago I encountered a term for this kind of person which I found deeply compelling. The word is provisionary (it's a noun, not an adjective). A provisionary is someone who looks ahead - pro vide, from the Latin roots. The idea of looking ahead is to plan for the future, see what potential needs and challenges are on the horizon, and then prepare for them. The best leaders are provisionaries; they exist solely to scout out the road ahead of their team, and make sure that road is as clear and safe as it can be.


Lately, though, it's occurred to me that this is not the sole responsibility of those who are "in charge" in the bureaucratic sense. To an extent, every member of the team should be doing the same, within their area of expertise. It's important that everyone have a unified vision of where the road should be going, and so it's best to have someone who is the "chief scout" so to speak who makes sure everyone is going the same direction.

However, no manager or team lead has the time or energy to see every single possible problem before it arises. Team members are on the team because they provide a unique and valuable skill to the team as a whole. This means that each individual on the team is uniquely positioned to see their own little slice of the road ahead, and prepare for it. A good leader needs to be in place to collect and correlate all of these little slices of vision, and reconcile them with the overarching direction of the team and the project.

What's interesting here isn't the leader's role so much; rather, there's an interesting perspective that needs to be present in each of the team members themselves. In most of the 9-to-5 corporate cultures out there, team members feel like they exist to serve their immediate superiors. Certainly their superiors rarely do anything to discourage this notion - and in fact in many places it is made quite clear that that is how the culture is configured. Employees exist to do the bidding of the manager.


So what happens when an employee, fully accustomed to this situation, is placed under the leadership of a provisionary? What happens when a team member operates like a drone grunt simply because he doesn't know that he has an alternative?

What happens is that the entire team suffers. It's not visible, not noticeable, and probably nobody will ever have any idea that it's going on. You could say that the team simply doesn't reach its full potential, but I don't think that really captures the seriousness of the problem. The team suffers - and it's the worst kind of suffering, the kind that is undetectable.


The solution is to cultivate an attitude of provision and service among every member of the team. When everyone truly feels and believes that they are a central, critical part of accomplishing something great, they will become more motivated, more productive, more concerned about the quality of their work. We all know that it's more fun to work on something you really believe in. Interestingly, this also feeds directly into your employee ego, which has huge benefits of its own.

A lot of people these days are talking about Google's management structure, their company policy, team organization practices, building layouts.... I think there are a lot of attempts to divine the "Secret of Google." Everyone wants to figure out how they are so successful. Is it the on-site chef and cafeteria? The funky paint colors on the walls? The nifty little glass-tent cubicle/office things? The opportunity for people to spend 20% of their time on personal projects? What makes Google such a powerhouse?

I think the secret is much more subtle and profound than food, paint, or dress code. I think the secret is that Google understands provisionaries, and it knows to cultivate that attitude in every single member of the company. I can't say for sure, as I haven't had the privilege of working there, but from what I can gather from those who do work there, that seems to be what's going on.


You want your team to have the success of Google? Heck, willing to settle for even one tenth of the success of Google? It's pretty easy. Just remember that every single member of the team exists to serve each other. Not your boss, not you, not the shareholders, not the quarterly earnings report. Each other. As soon as any of the trappings of corporate existence get in the way, you've lost the magic, and things will inevitably degrade. Your team exists for each other - nothing else matters. Nothing else exists.

Every individual has something they can bring to the team. (And on the off chance that they don't, it's time to take a deep breath and dig out the pink slips.) Not only that, but every individual should be doing all they can to help the team move forward. This means people need to care about the project enough to be bothered when there are problems. They also need to have the skills to find solutions to those problems. Finally, they need to have the initiative to implement those solutions.

It's actually pretty rare for one person to cover all three bases. That's why we have teams in the first place: because everyone's skills supplement and complement the team as a whole. That's where a leader comes in; it's the role of the leader to find people who can take care of all three areas, and make sure they do so. However, it is vital that everyone at least partially cares about the project itself; this simply doesn't work in an environment of complacency.


So how do you make people care about their project? Give them a tire pump for their egos. People can and should be proud of the things they've accomplished and are working on accomplishing. Back in the Olde Days, we spoke of "taking pride in one's work." That's really just another way of saying that you care about what you do - you care because the outcome of your efforts is a reflection on you. That emotional investment will do more wonders for your project than any cigar-munching, oak-desk management Vogon will ever be able to comprehend.

The secret is that taking pride in one's work isn't just something that each individual does for themselves - each team member (and especially the leaders) needs to push everyone else to take pride in their work as well. It's unfashionable to be an arrogant jerk, so many people will simply settle down to mediocrity so as to to rock the boat; nobody wants to be accused of being a prima donna. That's why the team has to encourage each other to be proud of their accomplishments - it's much easier to be proud of what you've done if people around you are proud of you, too.


When people care, they work harder, and work better. This is a pretty well-understood phenomenon. What's important is to foster a culture of caring, and of service. Each person needs to feel compelled to use any of their available skills to help advance the team's goals - and they need to have the authority and permission to do so.

The results can be truly amazing. I know, because I have the privilege of working on a team where just such a culture is being created.


But don't just take my word for it - look at this little company called Google. You may have heard of them.

Comments: 3 - Leave a Comment

Link



Wednesday, July 12, 2006
Today, I'm going to tell you how getting a mouse with extra buttons will make you richer. No joke, and no Nigerian scam.


We've all been there: you're supposed to be someplace, and it's a couple of minutes before you need to leave, so you plop down and fire up Minesweeper (or whatever your crack-equivalent-of-choice may be). You burn a little bit of time, but not quite enough - just one more game. Then you've gone about a minute past the time you were supposed to leave... but eh, who cares; traffic is light this time of day, and you can make up a couple of minutes, no sweat. Just one more game.

Soon, you're counting on hitting all green lights on the way. Just one more game. There's never any cops on that one road - you can really book it there and make up a couple extra minutes. Just one more game. You can acheive feats of physically impossible speed, you got bit by that spider this morning, and you're pretty sure it was radioactive. Just one more game. You haven't tested your power of teleportation just yet, but you can just sense that it works. Just one more game. Rewinding time? No problem! You just need a time machine... and once you've got a time machine, you can rewind as far as you like, so it doesn't matter how long it takes to actually get that time machine. Just one more game.

An hour later, you realize that where you were supposed to be is called "work." Oh, yeah... work. Didn't your boss say something about being late all the time? Something like "you had better haul your dumb ass in by 9:00 AM sharp every day for the rest of this month, or you're fired!" Hey, the phone's ringing. What a coincidence, boss! I was just thinking about you! What? Fired? Oh, shit.


Oh well... at least now you have time to play Minesweeper, right?


It's quite common to look at a task and judge its significance by the amount of time it takes. For the most part, this is a reasonable thing to do - in general, more difficult or complicated things take a longer amount of time. Building a house in Age of Empires takes less time than building a house of cards; building a house of cards takes less time than building a real house; building a real house takes less time than building a skyscraper; and so on.

However, this assumption can also be extremely dangerous. If all of human activity was fully independent, and divided up into discrete little blocks that could be shuffled at will, it wouldn't be a problem. We could look at a list of tasks, figure out how much time they each take individually, sum up the numbers, and have a complete estimate for how long a project will take.

Of course, if we try to do stuff like that in real life, we're in for a world of hurt.


The fact is, the impact a task will have on your flow of activity is virtually impossible to correlate to the amount of time it takes, when that time is relatively short (arbitrarily, I'll say less than a day). There are a couple of factors that come into play here.

Getting Started
This is a big one when it comes to programming in particular. Every practiced programmer knows about The Zone - that mental mode you have to be in to really get anything done. Different people take varying amounts of time to get into The Zone, and any number of factors can affect how long it takes - but it always takes some time. Therefore, if you're going to do some easy programming task, you can't just estimate how long it would take you to finish: you have to include the time it takes to get started.

Getting started is a difficult thing, especially when you face a large block of tasks. A commonly cited motivational technique is to force yourself to start one simple, small task; you'll spend a fair amount of effort getting started, but once you have started, moving on to other tasks is vastly easier. This leads directly into the second thing that affects our work times:

Momentum
The human brain obeys the laws of inertia. If you're stagnant and not doing anything, it's far more likely that you'll continue not-doing-things rather than starting on something. The good news is, once you're moving, it's much easier to continue on with other things. In fact, it can become so easy to continue that we drop into The Zone one morning and suddenly realize it's dark outside and we're really darn hungry.


These are very important factors to consider when thinking about time management on small scales. To an extent, they also factor in to large scales as well, but that's really a whole separate area of exploration. What I'm interested in today is how time management goes wrong on the small scale, and the consequences.

Work flow can be disrupted by many things. In general, though, these all fall under two simple categories: something happens that is not what we expected, or we don't fully plan on the consequences of something that we do expect. Any time this occurs, the result is jarring, and can have dramatic effects on work flow - not just for the rest of the day, but sometimes for days afterwards as well.


Disruption at the hands of The Unexpected
Your compiler crashes. Your wife/girlfriend/mom/alien guardian walks into the room and tells you it's time for dinner. You find a really cool Flash game and play it for four hours without realizing. Any number of things can occur that we don't originally plan on dealing with, and when they do, they really screw up the plans that we did have.

The most obvious danger here is the loss of momentum. When we're interrupted by something, it takes our attention away from what we were doing, and usually incurs the cost of Getting Started again. However, the obvious problem is not the most insidious or dangerous one - the real problem comes from the buildup of frustration

Over time, little things add up. One too many crashes can push a perfectly sane and rational adult over the brink into utter depravity and rage. This is a nasty problem, because frustration is a threshold function. Up until a certain point, we may not even know that we're frustrated - the focus on the work can be so intense that we never even realize just how stressed we are.

For instance, just yesterday I was working on a project close to deadline. In fact, it was slightly overdue, because of some unexpected bugs I had introduced in my sleep-deprived stupor a couple of nights earlier. It wasn't a particularly important deadline to hit dead-on, so I wasn't worried about it, but I definitely wanted to get things done and make up for the time I'd lost on my dumb mistakes. Then, out of the blue, my Internet connection dropped. When one is working on a codebase that lives on another continent, losing Internet connectivity is a huge problem.

That much was frustrating, but still I had no idea just how close to "totally pissed" I was. The last straw was when the VPN connection locked up and died, taking the source control software with it - and, by extension, locking up Visual Studio and losing a few minutes worth of unsaved work.

Long story short, some things were said which would make our seafaring friends blush, and there are a couple of objects lying around which weren't broken a few days ago. I went from being relaxed, in The Zone, and working smoothly, to utterly irate, and incapable of focusing on anything. I lost almost two hours trying to recover from that blow before I realized that I really didn't need to have the VPN up to work on the code, and that the work I'd thought I'd lost was just a single debug logging statement that I had been about to remove anyways.


Misjudging Consequences
Clearly, The Unexpected can do some major damage. As if that enemy weren't scary enough, there's an even more hardcore boss-monster lurking in the shadows. Many people understand the dangers of interruption and frustration; but what you don't hear about nearly as often is death by slow stuff.

I've noticed an interesting trend among highly experienced and highly productive programmers: there is a sort of threshold point involved. On the one side of this line, a programmer may be quite skilled and productive, but they just seem to peak out - they appear to have reached the limits of their potential. Those limits are impressive, to be sure, but they're not biblical. These people are often team leads and senior programmers on teams where political dysfunction hasn't put morons in those positions.

On the other side of that line, there's these sort of amazing über-hackers, who could crank out a running Doom clone in their sleep while in the hospital with 5 broken bones and a lung infection. They're the wizards, the superstars, the Free Electrons. They do magic, they singlehandedly save entire projects, and nobody quite figures out how they pull it off.

The difference is an important matter of mental perspective. This perspective is by no means the sole trick to becoming a legendary hacker - but it's an important part, and it's a trait that all the best hackers absolutely have to show. The telltale sign is an obsessive, unyielding, and non-negotiable demand for high-performance tools and hardware.


These guys demand the fastest, the best, the most efficient. Most of them have hotkey sequences and macros that do little tasks most of us don't even realize need to be done. These are the people who are hardcore devotees of Emacs, who write shell scripts to automate every little two-second job they've ever needed to do, and who seem to be pathologically mental about shaving milliseconds off of things.


The obvious question from us Common Citizens is why? Say you have some task that takes, on average, three seconds, like reversing all the letters in a highlighted block of text. Suppose we write a macro to automate that task, and it takes 15 minutes to write, and now any time we need to reverse some text, it takes only one second. The anal-retentive manager-types among us have already whipped out the calculator and determined that we have to run this script 450 times before it pays off.

OK, that one seems a tad far-fetched, but in certain scenarios it may be useful. But let's look at another nasty one, this time from my own experience: compiling a program and building an installation package. This task only takes, say, 8 minutes, and the vast majority of that time is spent waiting for the computer to do things - compile code, compress files, and so on. The main bit of human-interactivity is clicking a couple of buttons half way through the process. Automating the task could potentially reduce the wait time to 7 minutes and 50 seconds - but automating it will take two days of scripting, or, say, 15 hours. That means, if we think of time as little blocks that we can shuffle around at will, it will take 5400 runs of the packager for the time investment to "pay off."

The anal-retentive manager types are not happy. This frivolous automation is a waste, and since we'll never ship 5400 versions of the software, you'd damn well better not burn up valuable company time writing an automated system!


On paper, this looks pretty good. We can walk away from the situation smugly knowing we just saved some money for the company (because time is money!) and, if we got to yell at a programmer, we can feel extra-manly today.

In reality, that's a very, very stupid mistake. And that's the truth that ultra-productive hackers have realized: that time management is not a zero-sum game. There are effects far more complex and intricate than can possibly be handled by an Excel spreadsheet.


The emotional benefit of shaving milliseconds
Extremely productive people don't shave time off of their tasks to literally create a net time savings; in fact, in most cases, the cost of speeding up the task may never be recouped directly. That's a bit of a weird thing to handle, especially for anal-retentive manager types - it just doesn't make sense. If you're losing net time by doing all this millisecond-juggling, how can you be so much more productive than anyone else? (Read: how can you possibly be making me look so bad when you obviously suck at managing your time?)

The secret lies in the hidden emotional side. As with frustrations caused by unexpected disruptions, we usually don't even notice that this is going on. It's an extremely subtle effect, and unless you are specifically looking for it, it's remarkably easy to miss entirely. But hidden in that subtle little tangle of nanosecond cause-and-effect is an extremely powerful bit of truth.


Shaving milliseconds off of a task is not important because it actually makes the task faster. It's important because it makes the task feel faster. Every time we do something that takes time, a tiny little fraction of our brains steps aside and wonders, "can I possibly do this any faster?" Waiting for a program to compile, waiting for a program to start and get to a point where we can run a test suite, waiting for the results to print out on the dot-matrix printer so we can read the logs over a cup of coffee and slice of pie... even something as subtle as waiting to move the mouse across the screen to click an often-used button. All of these things add up, and every time we do them, that little doubt-circuit gets a little more sick of waiting.

If you can do a little bit of work to satisfy your subconscious mind that Task Q is running as fast and efficiently as it can possibly be, you will never again have those little doubts. The net result is that work feels less like work - it's smoother, more reliable, and more enjoyable. The less energy it feels like your work takes, the more you'll be able to do - the more momentum you will be able to exploit before running out of steam. It's entirely a mental game, but the stakes are high, and the pot is rich.


At this point, you're probably really tired of waiting for me to get to the point - how do multi-button mice make you rich? (You've probably even skimmed the top half of this entry just to try and find the Juicy Tidbits - quit being lazy and start from the top, you slacker! It's worth it - you'll see as soon as you read it.)

Here's the clincher: switching your hands between the keyboard and mouse is one of those little things that takes time. It's not much time, to be sure - in fact, I doubt anyone could make a case that it consumes a significant amount of time over the course of a programmer's career. But as we've already seen, the numbers can mislead us - not because numbers are dirty little treacherous bastards (although they are), but because the numbers don't capture the whole story. And the whole story is that the feeling of slowness is far more important than real passage of time.


I originally bought a Razer Diamondback Plasma mouse for my gaming machine. Recently, for no real good reason, I decided to try hooking it up to my development box. Since it was all set up, I figured I'd try an experiment, and map the extra 4 buttons it makes available. Two I have linked to Forward/Back in my web browser, and two are linked to Copy and Paste.

In the week since I've set this up, I've noticed a tremendous increase in how productive I feel - I'm running sessions a lot longer than I ever used to, and feeling less drained afterwards. I suppose it might be the illegal drugs I'm sampling on the side, but I suspect credit is due to the mouse buttons. They've saved me the trouble of moving my hands around more than I need to, and as a result my perception of my work experience has improved dramatically.

I've since bought a second Diamondback to permanently replace the old Logitech cheap-ass mouse I was using before.


So what's the moral of the story? No, it's not a concealed advertisement for Razer mice. (Although... if anyone from Razer is reading, feel free to drop me an email and we can talk about endorsement deals...) The moral of the story is that time management on a small scale is a tricky beast. Shaving down milliseconds is an important investment, even though it may not seem like it if we insist on treating time management as a zero-sum affair.

In the spirit of improving all you anal-retentive manager types (bonus question: how many times have I overused that phrase lately?), here's your action point for the day: go out and buy all of your programmers the fastest machines you can afford. Yes, the difference between 2.0GHz and 2.2GHz processors matters. Yes, I know the benchmarks say the price-to-performance ratio isn't worth it. To hell with the benchmarks. This is millisecond-shaving, and having the absolute top-end hardware will make your programmers that much less likely to subconsciously suspect that they are wasting time waiting for their computer to finish things.

Hardware isn't all, though - buy the latest and best tools. When applicable, consider buying a support license/contract and hiring someone to help streamline your installed tools. Divert a programmer or two specifically to go around the team and look for tasks that can be automated. Encourage everyone to set up hotkeys, macros, and other time-savers.

And put away that damn Excel sheet - you're not going to save time on paper. But I've got a nice shiny new mouse that says you'll become more productive as a whole.

Comments: 3 - Leave a Comment

Link



Tuesday, July 11, 2006
A longstanding tradition in my family is the making of Chex Mix. I'm the third generation of the family to carry on this hallowed duty. It began back in the days before you could get Chex Mix in little prefab baggies - and, I daresay, it's a lot better than the mass produced stuff.

The traditional family recipe is an altered version of one of the original recipes published on the back of boxes of Chex cereal. Today, I tried out some more radical modifications, based largely on my own whimsy.


Here's my version:
  • 1/2 cup (1 stick) salted butter

  • 5 tsp Worcestershire sauce (choose your favorite brand; personally I'm a Lea & Perrins guy)

  • 1 tsp Tony Chachere's cajun seasoning

  • 2 tsp dry mesquite seasoning mix

  • 2 2/3 cup each of corn, rice, and wheat Chex

  • 1 cup salted mixed nuts

  • 1 cup pretzel sticks

  • Preheat oven to 250F. Melt butter in a large roasting pan while oven is heating.

  • Mix sauce and seasonings into melted butter; blend thoroughly

  • Slowly stir in cereal and other stuff; ensure mix is coated thoroughly

  • Bake 1 hour at 250F, stirring thoroughly every 15 minutes


Came out quite nicely, if I do say so myself. (I actually used slightly different measures, but mine came out a little bit on the salty side - so I've adjusted the recipe a tiny bit to compensate.)


Unfortunately, I made the mistake of running the cleaning cycle on my oven right after this little experiment, so now the whole apartment stinks like charred grease, and it's hot as Satan's armpits in here. To top that off, I forgot to take out the oven racks, so they're probably going to be totally screwed up.

Oh well... it's worth it for the munchies.

Comments: 3 - Leave a Comment

Link



Saturday, July 8, 2006
Lookout, suckas. I'm motivated.





Couple of housekeeping notes:

- Superpig brought up a reasonably good point about the logistic interpolation, namely that it doesn't have a 0 gradient at the entry and exit points. There are some evil tricks that can be used to fix this, but I've forgotten them. When I get around to rederiving them (I'll need to for work anyways) I'll post up what I did. It actually isn't a problem for certain simple things, but if you try to use more than two control points you'll get "kinks" in the movement.

- I'm a tiny bit behind on work this week due to pissing around a lot with some mates of mine last night. It's very likely that we'll go piss around again tonight. This means I'll be doing work-work instead of stuff like TKC or Epoch, most likely. However, I'm looking at stealing a day or two from next week to dedicate to those projects.

- I'm not using a bulleted list here. That's how you can tell I'm serious. Actually, that's how you can tell I'm highly sleep-deprived, whacked out on artificial stimulants, and about to electrocute myself from all the drool on my keyb888uujjjjjjjjjjjjjjjjjjj

Comments: 0 - Leave a Comment

Link



Friday, July 7, 2006
Interpolation
Interpolation is a very common technique used all over the place, especially in computer graphics. Pretty much every game programmer can code a simple linear interpolation in his sleep. Interpolation is everywhere, especially in the realm of animation.

Linear interpolation is simple and easy. Unfortunately, it is also very limited, and produces ugly results when used for moving objects around. For a given set of control points, linear interpolation will produce very rigid, jerky movement, with abrupt changes in direction and speed. This obviously doesn't make for a very good result.

Typically, we will use more complicated interpolation techniques, such as cubic spline interpolation, to overcome this problem. A good spline interpolation is smooth and graceful, and can be controlled very precisely given suitable control points. Unfortunately, it can also become fairly expensive to compute, and setting up lots of control points by hand can be tedious.

Sometimes, we want just a simple interpolator that creates a nice smooth path between two given control points - and it'd be nice if it was fast, too. In the remainder of this post, I'll describe just such a technique.


Background
Let's start with a basic linear interpolation. The basic formula should be very familiar: y = (x - x1)((y2 - y1) / (x2 - x1)) + y1. This will give us a run-of-the mill linear interpolation of y between the points (x1, y1) and (x2, y2), given an input value of x.

Now, here's the important point: that function is just the result of a simple function that has been scaled and translated with a couple of simple transformations. The process of applying those transformations to a function is beyond the scope of this post, but it should be familiar from most high-school level algebra courses. Mathematically-inclined readers should already recognize that the linear interpolation formula is just a transformation of a simple base function, namely y = x.

The interesting thing about y = x is what it looks like inside the square (0,0)-(1,1):
y = x in the square (0,0)-(1,1)


This is the heart of interpolation: you first "squish" the inputs so that they fit into the square (0,0)-(1,1); then, apply the interpolation function; then "unsquish" the result to get a value in the original required range. A convenient way to think about this is as a percentage function. You put in some percentage of x, and out comes a corresponding percentage of y. If you know the percentage "distance" that x has travelled from the beginning of its range towards the end, you can convert that into a percentage "distance" that y should move as well.

For example, let's set up the control points (10, 50) and (25, 106). If we substitute those into our original linear interpolation equation and graph the function, this is the result:
Transformed function - linear interpolation


So, in theory, if we have any function that passes through the points (0,0) and (1,1), we can apply the squishing/unsquishing (transformation) technique, and then use that function for interpolation.


Logistic Functions
If you've taken a statistics course, you're probably acquainted with logistic functions. A logistic function produces a really nice, smooth S-shaped curve. In fact, it's a curve that looks like it would be just about perfect for doing interpolation...

Here's what the logistic function y = 1 / (1 + e-5x) looks like:
A logistic function


Looks nice, eh? Only problem is, it doesn't quite fit inside our (0,0)-(1,1) box: it hangs over into the negative x axis a bit. Let's translate it by 0.5 to the right, using the equation y = 1 / (1 + e-5(x - 0.5)):
Translated logistic function


This is getting better, but it still doesn't quite fit: at x = 0 it's a bit above the y axis, and it doesn't quite hit the y = 1 line by the time x hits 1, either. (In fact, strictly speaking, it never reaches y = 1 at all.) This means it isn't quite ready for use as an interpolation function yet. So let's apply another little transformation or two to get it where we want it. Our final equation looks like this: y = ((1 / (1 + e-5(x - 0.5))) / 0.8483) - 0.0894
Final logistic function



Perfect! But how did I come up with those two extra numbers? It's pretty simple, but it's an important trick, so remember it for later! Essentially we're doing a little bit of interpolation by hand. First, start by finding the value of y when x is 1. In our case, that value is roughly 0.92414. This is about 0.07586 away from 1, which is what we want the function to equal. So, multiply that difference by 2, to get 0.1517, and subtract that back from 1, which yields 0.8483. Divide the entire function by this value. Now, if you graph the function again at this point, you'll see that it's too high - it doesn't equal 0 at x=0, and it actually passes above y=1 when x=1. So, find the value of this new equation at x=0 - it is roughly 0.0894. Subtract that from the equation, and voilá - now the function fits into our (0,0)-(1,1) square.


Smooth Interpolation
Well, this is a plenty nice little graph, but it isn't quite an interpolator just yet. For that, we need to re-apply the squishing transformations that let us get a nice interpolation between any control points we want.

I'll spare you the tedious algebra, but you should be able to do this on your own - if you know the underlying mathematics, you can create your own interesting interpolation functions easily.

The resulting equation looks like this:
y = ((1 / (1 + e(-5)((x - x1) / (x2 - x1) - 0.5)))(1 / 0.8483) - 0.0894)(y2 - y1) + y1

And here's what it looks like when we provide the control points (2, 3) and (17, 11):
Smooth interpolation



Beautiful!


Extra Exercises
There's a few things you might play with here to get different effects. This interpolator will accelerate smoothly and then decelerate, but it's still only a subtle change over a linear interpolation. You can change the exponent part of the equation a bit to get a more or less "extreme" acceleration profile; the current exponent coefficient is -5; a value of -2 will be much closer to a linear interpolation, whereas a value of -15 will produce a very slow initial and final change, with an extreme rapid spike in the middle.

So far, all I've done is show an example of translating the function along the x axis. You can also experiment with multiplying various values by the x coordinate to scale the interpolation. This can be used (in combination with a suitable translation) to "bias" the acceleration/deceleration, so that the interpolation curves more rapidly at the beginning than at the end, for example.

Finally, you can get some truly interesting results by combining more than one function. For instance, adding a suitably transformed sine wave can cause the interpolation to "overshoot" slightly (it will actually go below 0 and above 1) which results in a sort of "imperfection." When used to control a camera, for instance, this has the result of slightly passing a point and then recentering on it, giving a very realistic and "human" touch to the result. You can also experiment with adding (or subtracting!) other functions like polynomials to get more complex curves.

The most advanced method of combination is composing two functions. For this, you first process the interpolation using one function, then re-interpolate with a second. (This can cause the squishing/unsquishing bit to be a little complicated, though.) I personally haven't found any practical use for such things yet, but you can get some very interesting behavior by doing this. Experiment, have fun, and see what you can discover!


One last tip
I highly recommend a couple of tools for this - a calculator and some kind of grapher. Graphing calculators are obviously the most convenient solution. However, a cheap pocket calculator (or even Windows Calculator) will suffice; combine this with a graphing package such as Graphmatica, and you're all set to play with creating interpolators of your own.


Now go forth and interpolate things... smoothly.

Comments: 2 - Leave a Comment

Link

Page:   1 2 »»

All times are ET (US)

In locus hic, omnes res dementes sunt.
 
S
M
T
W
T
F
S
1
9
10
17
18
20
22
23
24
26
28
30
31

OPTIONS
Track this Journal

 RSS 

ARCHIVES
July, 2009
June, 2009
May, 2009
April, 2009
March, 2009
February, 2009
January, 2009
October, 2008
September, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
March, 2008
February, 2008
January, 2008
December, 2007
November, 2007
October, 2007
September, 2007
August, 2007
July, 2007
June, 2007
May, 2007
April, 2007
March, 2007
February, 2007
January, 2007
December, 2006
November, 2006
October, 2006
September, 2006
August, 2006
July, 2006
June, 2006
May, 2006
April, 2006
March, 2006
February, 2006
January, 2006
December, 2005
November, 2005
October, 2005