My Photo

« August 2007 | Main | October 2007 »

September 24, 2007

TDD triumphs again!

We had a bug once where some enemies weren't moving with their correct starting trajectories.  I wrote a unit test and fixed it.  Today - the test failed!  And it was for real, because of a change I just made that had unforeseen consequences.  If the test hadn't been there, I would have checked in, and the bug would have sat there, probably until Richard or Skaff played the problem levels and noticed - which could easily have ended up being the night before our IGF submission is due...  whew.

September 22, 2007

*Schizoid* at Tokyo Game Show

Hey, if anybody reading this happens to be in Tokyo, you can head on over to TGS and see a demo of *Schizoid* in the Microsoft area. 

September 16, 2007

Top 10 Memorable Gaming Moments

#10 - Discovering that Exodus was a computer.

#9 - Kicking the alien in the crotch, rolling and grabbing the gun and shooting him in Out of this World.  (Closely followed by the sequence where you're running down the corridor, doors slamming behind you, which are then blown away by blaster fire.)

#8 - Realizing the shotgun damage was inversely proportional to distance in Doom, after which I started charging enemies like a madman to get the point blank shots.

#7 - The reveal in Bioshock.

#6 - Prince of Persia 2 (the original 2D one) - running and jumping and catching the boat as it pulled away on the first try.  Apparently POP1 had the shift-key-grab burned into my muscle memory.

#5 - My base being invaded in X-Com.

#4 - The opening sequence from Half-Life.

#3 - Playing Diplomacy at a convention;  they all had me figured for the weak player (which I was) but I surprised a bunch of them by cutting a support army in a key play and ended up coming in 3rd.  "Who told him that move?" one of them asked.  Came up with it myself, thank you.

#2 - A one-on-one Kohan game against a guy who usually won but always played skeleton hordes.  The answer is priests.

#1 - Beating my dad for the first time in chess.  "Today you are a man," he said.

What about you guys?

September 13, 2007

Notes On Bioshock

Bioshock has a Memorable Moment that I think is probably in my top 10 Gaming Memorable Moments.  And I've got to say, it's nice after the Halos and CODs and Gears of Wars of the world to play a game where resources are somewhat scarce.  I'm actually forced to conserve, which isn't always the kind of game I feel like playing but does make a nice change.  And, the art direction!  Wow!  If you're looking for a dark underseas art deco experience, Bioshock is the place to come to!

[Which forces us to ask the question - are the masses looking for a dark underseas art deco experience?  Or, are enough people looking to make Bioshock profitable, or is Bioshock like the Terry Gilliam movie - something I love but doesn't sell?  It's sold .56 million according to vgchartz.  Which puts it on track for selling over a million lifetime, but not much more.  Assuming the publisher gets $10 a pop, that's $10m.  Then, PC sales and sales over steam will add a chunk.  Take 2 owns the IP, an asset in their portfolio worth...what?  And how much did it cost?  Although Irrational is very good at making a fairly small number of levels, enemies, and systems go a long, long way - and most of the story is told in (excellent) voice-over - there's a long list of credits and it was in development for a long time.  $10M?  $15M?  So my back of the envelope puts it right on the edge of profitability - a place where most publishers don't really like to be - but Take 2 seems very pleased, so I've probably dropped a decimal place somewhere.]

And I could write a more in-depth essay, but instead I will indulge in the ultimate in lazy blogging:

First, a reference to an old article I wrote on System Shock 2.

Then. an IM conersation about Bioshock:

jdfristrom: I still haven't finished Bioshock
brett_douville: A compiler dependency seems to be busted in my .Net and it generates longer compiles than it should, which is super super super annoying
brett_douville: So I have some free time :)
brett_douville: How far are you now? I'm blogging in another mental thread about it
jdfristrom: How far am I from?
brett_douville: How far are you in BioShock?
brett_douville: (Though clearly you have your ship date on your mind...)
jdfristrom: (Yeah)
jdfristrom: I just saved the trees
brett_douville: Ah, right.
brett_douville: That might be the first time you see a normal human in the game, right?
jdfristrom: I'm wishing I bought the PC version - but gameflying the 360 version was free...
brett_douville: The plant lady?
brett_douville: I'd happily send you my copy -- but I Steamed it.
jdfristrom: I didn't know it was on steam.  Cool.
brett_douville: I didn't even have to leave the house.
jdfristrom: Heck, I'll switch
jdfristrom: It won't take me that long to get back to where I was
brett_douville: Really? It seems like you're a good 8 hours in, if I remember correctly
brett_douville: That's roughly the halfway point, I think, though maybe it's more like 1/3rd
jdfristrom: It'll go faster the second time
brett_douville: Anyway, that's when I noticed that the faces on their people looked super strange -- it totally works for the Slicers, but for a "normal" person, it's pretty ghastly
jdfristrom: I didn't get to see her that close
brett_douville: Yeah, I used the physics to knock her around a bit
brett_douville: The ragdoll is pretty twitchy in that game -- in RC, we only had the memory and CPU budget for one ragdoll at a time, so we would turn them off once they came to rest, and I think more games should do that
jdfristrom: Their corpse ragdoll is broken - we had similar problems with Spider-Man 2 - but I guess they just left it in because who knows what's going on in a dead Splicer's nervous system
brett_douville: Bingo!
jdfristrom: funny, I was typing that before you started
brett_douville: great minds and all that
jdfristrom: I can totally see that bug lingering on the buglist for the life of the project
brett_douville: Yeah. Although, overall, I wasn't impressed with their ragdolls. Not that it matters all that much. But they seemed too springy.
jdfristrom: I can't be sure, but I think I liked SS2 more
jdfristrom: I don't think SS2 had the resurrection stations...if it did, there were fewer of them, or there was some bigger cost
brett_douville: I don't think they had them at all -- I think it was a reload situation if you died.
jdfristrom: It creates a weird economy - "I better not use my health kit, but that costs money!  And resurrection is free, as long as the tube isn't too far away"
brett_douville: But SS2 could be so broken, which left a bit of a bad taste in my mouth -- I got very close to the end of that game and it was literally impossible for me to complete it.
brett_douville: Yeah, I tended to rely on the res stations for Big Daddy combats
jdfristrom: I imagine something like this happened
jdfristrom: "We need to make the game easier to bring in more casuals."
jdfristrom: "Let's have resurrection stations."
jdfristrom: "Hey, now the game is too easy."
jdfristrom: "Let's make killing a big daddy require an absolute crapload of health."
brett_douville: Yeah, I can see that exactly. But a casual user won't. He'll just be happy that he's not reloading.
jdfristrom: Ok, if you had trouble with the big daddies too, guess I'll stick it out with the xbox.  I thought maybe it was because I didn't have mouse & keyboard
brett_douville: Well, it could be that I suck. But I prefer not to think that way.
brett_douville: I was going to buy an Xbox360 for it, but really, it just didn't make sense. Until Tim Schafer's game comes out for the 360 (assuming that to be the best sku for it), I probably don't need to buy a 360 at all.
jdfristrom: $300 to be able to play Schizoid is a bargain, mind you.  But we'll probably port to the PC eventually also
brett_douville: But don't I really need someone else to play with to fully enjoy it?
jdfristrom: What am I, chopped liver?
brett_douville: Oh, we're going to play, with our 3 hour time difference?
jdfristrom: I'll finally have some free time...
brett_douville: I may have to give up sleep altogether. I play co-op every now and again with friends in California, but we start at 9. Their time.
jdfristrom: How old are Luc & Jordan again?
brett_douville: 9 and 7, respectively
jdfristrom: Luc'll play it with you.
brett_douville: They'd want to play together
jdfristrom: On a different note, I wonder how long it would take to kill a big daddy with just the wrench
brett_douville: Ugh. I can't imagine trying.
brett_douville: I can remember some great times in the original Doom (or perhaps Doom II) where you'd get the quad damage and invincibility and be punching out cacodemons and stuff
jdfristrom: Yeah, those "You're temporarily incredibly awesome" moments always work - the Scorpion in Halo was another good one
jdfristrom: the final level of Half-Life 2...
brett_douville: Yeah
brett_douville: You need to finish BioShock so I can discuss one thing they did with you
jdfristrom: It may take a while, because I've decided I'm going to only use the wrench
jdfristrom: j/k
brett_douville: Ha! That would invalidate what I was going to talk about anyway :)
jdfristrom: What was your preferred method for killing grunt-level enemies?
brett_douville: I tended to just pistol to the head
jdfristrom: how many shots did that take?
brett_douville: But I never felt too light on ammo in the game, so I didn't worry about it too much
brett_douville: Two
jdfristrom: did you play normal difficulty?
brett_douville: yes
jdfristrom: I can get off one headshot on an unsuspecting one but never the second one - and it seems like it takes about half-a-dozen body shots to take one down
brett_douville: The shock + wrench works very well
brett_douville: If you can shock before you shoot, that's usually pretty quick too
jdfristrom: I always feel strapped for ammo - I feel like ammo's for big daddies - yeah, I've been using shock + wrench + wrench jockey + stealth wrench
jdfristrom: But they always get one hit on me
brett_douville: I rarely felt strapped for ammo -- lots of weapons, you can buy more whenever you need to, etc.
jdfristrom: Which is okay, since the resurrection tubes make health practically free, but I'd rather spend 2 bullets
brett_douville: I wonder if they are balanced differently PC vs 360 -- you'd think they'd have to be
jdfristrom: 360 easier, to account for tougher controls, or 360 harder, because audience more hardcore?
brett_douville: Late in the game I was always leaving ammo behind
brett_douville: Um, I'd say 360 easier, because 360 less hardcore?
jdfristrom: Or, yeah, could be that
brett_douville: I'm sure the game sold more copies to mainstream players on the 360
jdfristrom: Which means I extra suck
brett_douville: No, no, no, no, no. Well, yes.
brett_douville: I wonder -- I'd love to know what they did for difficulty. I always preferred the simplest possible solution (i.e. you do more damage in easy, less in hard).
jdfristrom: if I were them I'd have a mode - maybe uber-hard - where the tubes are turned off completely
jdfristrom: other than that, yeah
brett_douville: Wow, yeah, that'd be pretty nuts
jdfristrom: eh, you could still beat it with quicksaving
jdfristrom: and, if you're good enough to kill someone with 2 or 3 bullets, you'll never run out of resources
brett_douville: I think I would mostly die not because I was out of health packs (which are really cheap), but because I wasn't paying attention to my health meter
jdfristrom: does it pop up the reminder on the PC version?
brett_douville: Yeah, actually, but sometimes I would  be so focused on the gunplay that I would ignore it
brett_douville: Which is a sign of good gunplay
jdfristrom: it pops up a little late, so two quick hits will kill me
jdfristrom: often I press the button just out of reflex and then say, "I should have saved my packs, there was a tube right there"
brett_douville: I tended to mostly get killed by the daddies -- I'd be so focused on dodging their rush attacks that I'd miss the health warning and then miss a dodge at some point
jdfristrom: they haven't been rushing me lately.  they take me out with their rivet guns
brett_douville: Ah yeah, the Rosies. I tended not to die from those -- just the chargers.
jdfristrom: how much health would a Rosie suck you down?
brett_douville: Probably 4 or 5 bars.
jdfristrom: That's $60-$75...yeah, that's worth it, a lot cheaper than the ammo
brett_douville: Yeah, health is super cheap
brett_douville: All wrench for you now :)
jdfristrom: It just occurred to me - I've been playing kind of quake-like, trying to circle & dodge while firing - but since health is cheap & ammo's expensive, it might be better to just suck up the damage and make absolutely sure my shots hit
brett_douville: Ah. Yeah, well, I've never been much of a quake player. I definitely played the game more like a tank.
jdfristrom: Can I just cut-and-paste the bioshock parts of this conversation into my blog?  I was going to do a "Notes on Bioshock" but I think we already covered everything in here
brett_douville: Sure, have at it. I've been blogging during compiles today with my own BioShock stuff, should be ready to go by tomorrow. :)
brett_douville: You won't be able to read it though.
jdfristrom: Oh, spoiler?
brett_douville: Yeah; I've decided not to worry about spoilers any more. I'm just going to go ahead and write whatever. I may add "caveat lector" to the stuff at the top.

Actually, one more thing.  And this is a bit of a spoiler:

There's a bit in Bioshock where you lose control of your powers - you can no longer choose which power you have armed - the game picks it randomly for you and changes on a regular basis.  This is awesome, and genius, and great fun.  Because all the spells are powered by the same resource, I (and most people, I'm sure) quickly settle on a favorite and don't even experience the other powers in the game, but this bit forces you to.  I didn't want this segment to end - it suddenly became a game of "How can I make this power that I'm stuck with work for me?"  I'd love to see a whole game built around this...the amateur magician who can't control which spell he's casting...

September 11, 2007

Manager In A Strange Land: Accuracy vs. Precision

One of my pet peeves is when people mix up the terms "accuracy" and "precision" - a pet peeve I picked up from reading Steve McConnell's *Rapid Development*.  (Page 173 of my edition - it's in the index!  What a great book.)

Suppose someone asks you for an estimate.  You say, "I think it'll take around two weeks."  They then ask, "Can you be more accurate?"

You probably cannot, not without a crystal ball.  (That said, there is a way to cheat to make it seem like you're more accurate.  That's below.)  But that's okay, because what they probably mean is:  "Can you be more precise?"

"Sure," you can then say.  "I think it'll take thirteen days, four hours, eleven minutes, and fifteen seconds."

Steve McConnel says "False precision is the enemy of accuracy."  Because now, when you take twelve days and zero hours to deliver, you've proven that your precise estimate was, in fact, inaccurate.  But your imprecise estimate (around two weeks) is still accurate.

But, well, come on, Steve!  Would *you* fund a project if they told you, "Well, it'll take somewhere between 10 and 20 million dollars."  No.  But you might fund a project if they told you, "It'll take 20 million dollars at most."  You - and by "you" I mean "me" - are kind of illogical that way.

So, the cheat is this - sandbag on your estimate ("It'll take three weeks and zero days") and finish early.  Also known as "the Engineer Scotty method."

We typically give a highly broken-down, itemized list of features and requirements to our potential clients, each with its own (admittedly overly precise) estimate.  Then we run some math on the back-end to account for "Fristrom's Law" and our historical velocity, and then we add a contingency buffer - that's the sandbagging that will protect us from our overly precise estimate.  Because if we slip, hey, that's our responsibility.

Of course, our competitors don't seem to be putting padding into their estimates.  Which means we often lose the bid.  But that's okay: the alternative--the risk of ending up contractually bound to a project where we're losing money--is worse.  And who knows?  Maybe our competitors will screw up their projects and we'll be remembered as the "honest guys" and we'll get the next project.

What do you do when someone asks you for an estimate?

September 09, 2007

Manager In A Strange Land: Time To Failure

We're all old hands at measuring quality in terms of number of live bugs.

Another metric I sometimes like to use is "Time To Failure" - how long can you play your game before you get to a stop-shipment bug?  (I almost called it "Mean Time To Failure", but when your sample sizes are typically one, saying Mean Time To Failure is...snooty.)

A combination of C#, TDD, soak testing, and having a small team and smallish scope have helped keep Schizoid's "Mean Time To Failure" very high - it's typically hours or days of soak testing before a crash bug hits us.  I haven't seen a project this continually solid since...well, ever, actually.

How can you get your TTF up?  It's fairly simple - play or soak test the game - and make the first failure your highest priority.  Lather, rinse, repeat.  You'll probably find this interesting side effect is progress on this front is exponential - your first bug may come in one minute.  Fix that, your next bug comes in at two.  Then four.  Then eight.  Just statistical likelihoods - if you have a crash bug that happens on what out of every 600 frames, that's going to bite you on average every ten minutes.

Now, it's been a while since TTF has been on our radar - our first soak test crash bug was actually marked Priority 2.  Whoops.  So it's been languishing there, even though it makes the soak test crash within 15-30 minutes.  After fixing that, the next crash bug happens around 45 minutes.  Just fixed that, and we'll see where our TTF is after that.  (Note from later - one at the two hour mark, and the latest run I shut down after four to tweak the soak.)

Why get your TTF up, you may ask?  Why does it matter what order you fix your stop-shipment bugs in?

Partly to look good to your client or publisher or boss, sure.  But also for morale!  If your game crashes a lot, people on the team are going to start to feel doomed.  And why should they fix their bugs when there are all these other obvious bugs in the product?  But if your game *doesn't* crash, then you can start feeling like you have a culture of quality on your team.

Just the other day, we were talking about crash bugs in Schizoid, and Skaff said, "Schizoid doesn't crash."  That was back when our TTF was a little higher...but that's what I'm talking about!  Good feelings all around.

So, I showed you mine.  Who will show me theirs?  Questions for the crowd:  1)  Do you know (or can you guesstimate) your own TTF on the game you have under development?  and 2)  What is it?

September 07, 2007

Huh

Ever look at some strange code, say "Who wrote this?" then look it up using your source control's Blame feature and discover it was you?

(Someone snarky out there could now say, "No wonder Schizoid is taking so long.")

September 06, 2007

Manager In A Strange Land: Fat Build Processes Redux

Gregg's comment was so good I'm going to escalate it.  He describes what is truly the perfect build system, an ideal we never reached on the Spider-Man team while I was at Treyarch.  And I'm jealous:

Wow, I almost violently disagree. First off,

"But if that's the case, how come most of the succesful studios I know do it the "antipattern" way (anyone using Unreal with its wad files, for example) and the teams I've heard of with the big fat build systems are catastrophic?"

Hmmm, nearly every team I've worked on and every product I've shipped has done the big fat build. Our processes were closer to the one Josh mentions but you could type "build all" and get all the assets rebuilt from source. Having artist manually shepard stuff is the ultimate nono in my experience.

That said, I think we might be mixing ideas. The ideas above can be broken down

1) It should be possible to automatically rebuild all assets with one command from source materials

This is so you can make huge architechural changes in safety.

(We could rebuild a lot, but not from the MAX files, from intermediate text files that were exported by the artist from MAX.  So we could make huge architectural changes to the renderer, but not to some of the other systems.-JF)

2) It should be possible to quickly build any single asset

Otherwise you have the long waits

(We had that. -JF)

3) When building a single asset, it should be possible for the system to automatically build everything else that asset needs (ie, if the Island level needs the palm tree asset then building the Island Level should also (optionally) build the palm tree if it needs to. If the palm tree needs the palm-leaf texture that should get converted.

Otherwise you have to hunt down the missing unbuilt assets

(We didn't have that but there weren't many dependencies - mostly just mesh -> texture, and it would load a placeholder texture when it couldn't find it.)

4) Assets should be built from source

Otherwise they get impossible to edit because all the stuff that made them easy to edit in the first place can get lost.(contraints, layers, IK rigs, expressions)

On top of that building from source means the source gets checked in. Which solves the "I lost the source" problem that here about on other teams.

(Yeah, artists could forget to check in MAX files.  Everyone had automatic backups.  What about PSDs?  Those can be expensive to check in. -JF)

5) updating a source assets should build any assets that depend on the fact that that asset changed.

Otherwise you either manually remember to rebuild those other assets which requires hunting things down.

None of this is that hard to setup and there are lots of easy ways to optimize, safe guard, etc.

Examples:

-Speed-

*) Building some assets (a level) can be slow so in our current system when any user builds an asset the command lines and source files (and tools) are MD5ed (MD5s are cached so they don't have to be re-MD5ed) and the MD5s compared. If they match then the baked file on the server is going to match what the user is trying to build and so it's copied off the server instead of built locally

-starting from source-

*) Exporting is easy to automate. Maya has mayabatch or you can write your exporter to run using OpenMaya as an executable. So there's no need to have artists manually export. Max has Maxscript which can be called on launch through the commandline so it can be automated as well.

(One of the reasons we didn't do this was because of the funky way we exported animations.  -JF)

-being flexible-

*) Version FOLDERS can be useful so that if a major format update happens you change the path the tools write to by version. So for example instead of storing the result in data/models/tree.bin it's in data/(version)/models/tree.bin where (version) changes with each file format change. Then the code is also updated to load that version. The result is people who have not updated the code or tools still build to and run from the old folders. Programmers working on tools or artists working with them on new features can safely move ahead

-starting from source-

*) If Excel is easier for artists/designers to use for data entry it's trival to parse its XML. (see my website for examples). Its XML stores everything so there's no reason to use XLS files ever which means no manual steps for that data either. Exporting to CSV or running some macro will both end up which chances for error and other issues and should be avoided.

That's just off the top of my head but anyway, the point is that yes, if you have the system you described that you type "build all" every morning and then wait 1~2 hours then yea, that sucks. But only alternative is not "hand build everything and have no build all ability". There are plenty of other and *better* options.

Oh, and as for Unreal people using the non big build. Every unreal project appears to be 6 to 12 months late using the non-big build. The projects I worked on shipped on time. (yea, I know that's an anecdotal point but then so is yours :-p)


Gregg's system is the best of both worlds.  You don't have to check every single dependency whenever you make any trivial change to the project (the way XNAGS is currently setup) -- I think we can all agree this is horrible and won't scale -- but you've got the big build which you can use to make burns and to validate source assets.

So here's a question:  do you build this elaborate system up front, or can you evolve up to it?  The Spider-Man team's build system was continually improving, and may have eventually arrived to Gregg's ideal after I left, I don't know.  (FWIW, Spider-Man 2 shipped on time with only a partially implemented "big build" as Gregg describes.)  Should we have halted production for a while to make it perfect?
 

September 05, 2007

Happy Birthday To Schizoid

It was one year ago today that I wrote the first line of code of Schizoid.

How time flies.  A year ago, I never imagined that making a downloadable 2D game would take this long.  Especially since we'd found the fun so early! 

But this is the first project I've worked on where it's okay to take as much time as we need.  Where we can chant "We'll ship it when it's ready!"  We're all about quality first, time to market last.  No contest.  You want network play?  You got it.  You want better AI?  You got it.  You want more graphical awesomeness all over the screen?  You got it.  A bunch of other stuff that we're not ready to announce yet?  Sure.  But we're not total suckers for feature creep.  I've been keeping my own words in mind - and asking "Will This Make The Game Better Or Just Make It Bigger?"

Still, can't wait for other people to be able to play it!



September 03, 2007

Manager In A Strange Land: Fat Build Processes Considered Harmful

Working with the XNA GS content manager is a mixed blessing.  The content manager subscribes to this philosophy:

In a perfect world, we wouldn't check in our game-ready assets.  We'd check in our raw, source assets only and our build systems will build them locally using the parameters we've defined.  If you want to change the compression, resolution - or even maybe the gamma ramp or color saturation! - on a texture or mesh, you just tweak a number and then everyone, on their local machines, the next time they build, get the new parameter.  Also, a change in an art asset would percolate through to all the levels on which that asset is used automatically.  Most importantly it insures that the source assets are actually checked in.

Sounds pretty good, right?  I've even heard it said that doing it the other way, the way where you manually build some of your game-ready assets and check those in, are an "antipattern in game development."

But if that's the case, how come most of the succesful studios I know do it the "antipattern" way (anyone using Unreal with its wad files, for example) and the teams I've heard of with the big fat build systems are catastrophic?

What I've found is that in this non-perfect world we live in, computers are just too slow for the "perfect" build system.  Because for every file that you need to take down the chain from raw asset to finished shippable product, you have to do a dependency check.  "Did this file or its parameters change?"  And the dependency check takes finite time.  And on your typical big-budget console or PC title, you have tens or maybe even hundreds of thousands of files.  That's if nobody changed anything.  It turns out it's way too much time to do every time you hit the "build" button (which is the way it currently is with XNAGS, which would probably have to changed or worked-around if you wanted to do a big-budget game with it). 

So now you've got a choice - you can provide your artists two ways to get their assets into the game (the slow way, build everything; or a back door to get an individual texture in) at which point you no longer have the perfect build system...or you can make your artists suck it and wait a few minutes every time they actually want to see one of their changes in the game.

And that's for a build where nothing has changed.  Typically, you come in the morning, you do an update/get/sync (whatever your asset control system calls it) and hundreds of files have changed because you're working on a team.  YMMV, but this can take up to an hour depending on how much has changed and how slow your build processes are.  So you've got your artists sitting idle in the morning, waiting.  If they're working together on something, and need to pass assets back and forth, then after Person A checks in his change and Person B gets it, Person B has that up-to-an-hour wait to start working with Person A's stuff.

This isn't likely to change in the near future!  The size of our games seems to be increasing just as fast as the speed of our hard-drives.  Maybe even faster. 

Which is why on most of my last projects we didn't subscribe to the "perfect build system" philosophy, as much as we would have liked to.  Artists shepherded each asset from raw to console-ready and checked everything in.

The biggest problem with this sytem - and the reason the "perfect build" is so appealing - is an artist could forget to check in the source asset.  Another artist might then work on the same asset by accident, or the first artists' hard drive might crash and the source asset might get lost forever!  These problems don't happen often enough to be worth the cost of the "perfect build" - and they can be solved.  The first problem can be solved by setting up the asset control system intelligently - the second problem can be solved by local backups.

XNA's content manager is tolerable for us, because we only have 2000 files.  On my machine a nothing-changed build takes 15 seconds, which is fine (though I'd prefer 0 seconds), and less than our load times.  If we had 20,000 files it would be a problem.

So, next time you're bitching about Unreal's wad files - just remember the alternative is worse!

Now, I expect a lot of comments after this post, because this has been good holy war material in sweng-gamedev, so let's have them!