Wednesday, August 31, 2005

Hurricane Katrina

I'm a really long way away from the disaster area (thank goodness), but after reading news channels today I felt the need to post, even though it is hard to find words to express just how wretched things are down there. I'm dismayed that looters have fallen to attacking hospitals (and aren't being shot by the national guard/police for trying), saddened that so many people seem to have died despite an evacuation order, and annoyed that New Orlean's flood/hurricane defence shore-ups were issued just 1/6th of the requested amount by the current administration last year. Months ago, there were reports that if a hurricane hit before a huge investment was made in flood defences (including wetland renewal, dyke infrastructure, and so on) this would happen - and funds were used for the Iraq war, and domestic counterterrorism instead. That's disgraceful, and really should be impeachable. I'm also disappointed in Homeland Security. Their evacuation plan completely ignored the poor and sick, or those without vehicles. Amtrak were even allowed to get away with leaving passengers at New Orleans stations (with transfer tickets, no less), before driving the empty trains to safety!


Anyway, this is probably not the time for recriminations. I hope the death toll is lower than currently feared. :-(


Mood: tired
Music: None

Friday, August 26, 2005

Asheron's Call 2 is officially dead

I just saw the news that Asheron's Call 2 is closing its doors for good in December. I can't say I'm surprised that it is closing, although I expected Turbine to cling onto the game to avoid the bad press of a closure before releasing D&D Online and Lord of the Rings Online (assuming they have the funding to still release these games). I played AC2 from beta until about seven months, was part of a pretty decent guild (when not overrun with annoying powergamers and uber-leet speakers), and thought the game had potential - but was almost a case study in mismanagement.


In late beta, and around launch, a lot of basic functionality was broken. Rubber-band lag when you moved, chat didn't work, and there wasn't much balance between classes. Crafting was nerfed, un-nerfed, and then forgotten about with promises of a revamp (ever fading into the future - apparently it arrived late last year). Levelling was a treadmill, and repeatedly doing the same quest over and over again was considered content. Microsoft and Turbine clearly didn't work as a team, and would blame each other when bits didn't work. Ken Karl and Ken Troop - the two architects of the game - left after a few months. Ken Troop moved on to head D&D Online (where he is being flamed left and right for what looks like a truly innovative - and utterly unworkable - game design), while Ken Karl quit the industry altogether. I gained a lot of hope when Jessica Mulligan joined the team to turn AC2 around. She managed it with Anarchy Online, and was very important in Ultima Online; that, and her Biting the Hand series showed great insight. Jessica made a lot of promises, some things changed - and suddenly the game worsened. Content patches became every other month (despite montly content being the differentiator of the AC product line over others). Gross revamps and skill resets hit everywhere, and it was obvious that the game lacked the manpower to make the sweeping changes required. We were promised everything from storage (banks, as found in every other game), vendors, NPCs who talk/move, buildings with interiors - the sorts of things that one might expect to find in a modern game. We received nerfs, constant bouncing between ideas, and the constant hope of promised changes. I left the game, but kept following it much as one might watch a train wreck as it progresses. Citan took over as leader of AC2, with Jessica suddenly in charge of AC1 and 2. She quietly (unannounced) moved to AC1 only, while Citan struggled to turn the game around. Things did actually improve; Hero 2.0 (flawed but better as an end-game), Crafting 2.0 (much like WoW's crafting system), a fair chunk of content, and some nice engine fixes. The developer team kept shrinking, and when the expansion was announced - all monthly patches were suspended to let them work on it. Apparently the expansion was a Hail Mary move: all or nothing, the game sinks or swims based on sales. Unfortunately, Turbine demonstrated an inability to market themselves out of a paper bag, and sinking became the only option. Citan is now working on Star Trek Online, Ramen (my favourite developer at Turbine) is manning the AC2 helm - she seems to have been elected to guide the ship into the depths, and the others are silent. I really hope Ramen finds a good job, she's a great developer, and really nice. It helps that she looks like Arwen, too. ;-)


I think seven months from expansion to close is a record. Horizons and Shadowbane have outlasted AC2! I wonder if this will spell the end for Turbine? MMOs closing is relatively new territory, and has been really bad for every company to go try it. Closing before two 'blockbuster' titles seems suicidal - and they aren't even offering those who stay to the end freebies in the new games.


Mood: tired
Music: Iron Maiden - Fear of the Dark

Friday, August 19, 2005

Not too bad...

I've been sick a lot lately, but that seems to be improving. I'm not
quite as broke as I was, although I still have some debts to pay off
(the IRS being the biggie!) before I can be truly comfortable again.
Work is hectic, but rewarding - some fun web development, and I'm
pretty confident that my Persist/Horizons framework is about to hit a
major breakthrough point. The PDF reporting system in particular is
taking shape nicely, and my MVC/plugin architecture works really nicely.



I've been playing a lot of World of Warcraft. Wydgette is now a level
20 warlock (not bad in 1.6 weeks!), and can handle most PvE quests
really well. I've yet to end up in a PvP battle with anyone remotely my
level, which makes me feel better about all the PvP deaths I've
accrued! I actually brought down a (level > 26) in a one-on-one
fight, but I died seconds before my various Damage-Over-Time spells
killed him. Still, I'm not really seeing why Warlock is regarded as
gimped yet!



I need to squeeze more hours into every day.


Mood: relaxed
Music: None

Saturday, August 13, 2005

On fear of change in game development: my modest proposal

Gabe Newell of Valve recently gave a really interesting interview, available here: http://www.next-gen.biz/index.php?option=com_content&task=view&id=510&Itemid=2




The funny thing is, I disagree with him completely. His basic premise is that multi-core systems mean that game developers need to throw away their existing code base, and many of the threading issues in game development are unsolved or only exist in Doctoral theses at present. Finally, he states that "Really good engineers are going to be much more valuable and engineers who used to be valuable writing game code in the previous generation may end up becoming thorns in the side of key programmers who can write multi-core game code."




First of all, my comment on the last sentiment: GOOD! It really is about time that good software engineering came to game development, rather than the backwards hackery seen so often. I'll expand on this throughout my discourse.




There are several fundamental problems with game development at present. The first is gradually being solved: a bad mixture of Not Invented Here syndrome, and wheel reinvention. Far too many games bake their own engine from scratch (often focussing on graphics to the exclusion of all else), when all they need to do is implement a similar rendering pipeline to other x generation setups. Innovation is needed, but for developers who aren't focussing on a new engine, this is wasted effort. Worse, many, many games are still written in C, with a gradual move to C++. Until recently, it was still common to see arguments on Flipcode and Gamedev against OOP design and established design patterns on the ground that vtable lookups are slow (they are really fast on modern compilers). Java, C#, and other modern languages are relegated to the status of laughing-stock because they abstract the hardware a step further away from the programmer with a VM (virtual machine). This is the first reason why moving to multi-threaded programming is difficult for many game developers: they are using ancient paradigms, while the business and scientific community has long since moved on.




The second fundamental problem of game development is an obsession with close-to-the-metal code, even when it can actually hurt your system! I've seen many cases in which assembly language is used, even though the assembly produced is actually slower than CPU-targeted compiled code. In a world of out-of-order execution, smart compilers, and different optimizations working better on different architectures (such as branch misprediction killing performance on the P4, but not the Athlon), compiled code � particularly high-level compiled code with high-level optimizations � is frequently more efficient than hand-tuned assembly. There are exceptions, but these tend to be special cases such as vectorization � and the compilers are catching up. Most fundamentally, micro-optimization abounds when the correct solution is to pick a sound algorithm in the first place.




The third fundamental problem in modern game development is an insistence on linear execution. Almost every piece of game code I've seen assumes a single message loop (the badly written ones eat 100% CPU when idle by polling for messages in a busy loop!), and tacks game logic in a neatly ordered loop. If you do this for server code, you may as well give up on ever serving more than a handful of clients at once � as server designers have known for 20 years or more. Games are no different. Even on a single CPU, this gives disadvantages: the scheduler cannot pass messages to your program while it performs actions prior to polling the message queue (meaning your program can appear to lock up hard, taking the system with it if you didn't clean up exclusive DirectX locks), IO requires a hard pre-empt from the kernel (meaning an unpredictable context shift � possibly in the middle of a frame calculation - if you fill the disk cache), and any other programs the user has running have a difficult time remaining usable. For hyperthreaded systems, it is likely that the second execution thread will actually slow such setups down; the game is probably using most of the execution units, and doesn't play nice with addition processes that desire some CPU time.




In other words, game development is (outside of graphics research) stuck in the early 1990s. Multi-threading is not difficult; if it were, I wouldn't use it in every Windows application I create, nor for simple tasks like separating data collection from display in a traffic monitor under FreeBSD. The key is a very strong design, isolating thread contention for resources as much as possible. There are many, many, books on this topic. Admittedly, most don't talk about games directly, but it doesn't require a Ph.D. to extrapolate basic computer science principles! Hopefully, the move towards hiring �really good engineers� will mean that code design will catch up in game development! It isn't hard to lock shared structures (via critical sections, spinlocks, etc.), it just requires that you think about access patterns.




The funny thing is, multi-threading is a shoe-in for most games. Physics should run independently of rendering � and I've seen many timer hacks to achieve this. Why not just put the physics engine in it's own thread, and render snapshots of the world? (Some physics problems are parallel in nature, and could even use multiple threads themselves!) Likewise, user interaction is a naturally threaded problem. Why should you only care about the keyboard (or other input device) status at a certain point in the loop (and revert to using DirectX's buffered input mode if you are concerned about missing events)? You might get a considerably more responsive game by checking IO in a timed thread, and feeding instructions to the phsyics engine. It might even be worth switching to an event-based IO system, in which the main process passes events to relevant threads; it works for every other interactive system out there! Even Ultima Online recognized that mouse input belonged in a thread. Likewise, sound really belonds in a thread with a priority that requests activity frequently enough to ensure that sound doesn't skip even if something else has slowed down (I believe some iterations of the Quake engine separated sound for this reason). Graphical rendering is often linear in nature, but could also be its own thread, so as to separate it from the main execution thread (ensuring that a bug will not freeze the main application thread).


How does one separate all of this game data to avoid contention/locks? Have each thread work with local data, and place data ready to be rendered (essentially a snapshot, although for IO it could be a queue) into a shared area when ready. Yes, you will need to lock this, but a copy should be a fast operation relative to the actual calculations � and you can start work on the next frame while the renderer lets the user know what's going on.


In a single-core system, this may not offer much advantage � but is unlikely to seriously slow you down. Modern schedulers are very good, and give the illusion of simultaneous execution rather well; if your graphics thread is waiting on a vertex buffer upload (handled by the GPU over AGP/PCIx), why not let the scheduler keep another part of your game running? On future multi-core systems, it is very likely that you can significantly improve the state of AI, physics, and general responsiveness with this strategy. Tim Sweeney of Epic has indicated that the Unreal engine will benefit greatly from multiple cores fo this very reason � there is no reason for other game developers to fear them.




Finally, the great language debate. Recent benchmarks show that languages contained in virtual machines (VMs) are very nearly as fast as C++, sometimes faster depending upon just-in-time (JIT) optimizations. Garbage collection, while occasionally slow (usually slowness in GC is an indication that you've done something wrong) makes cleanup very easy. Study after study shows that for most logic, higher-level languages make programmers considerably more efficient; no more re-inventing basic structures, for one thing. More importantly, modern languages are built for the multi-threaded world. Managing Windows threads in C++ with the Windows API is painful (but quite manageable). Managing them with the C# threading library is very, very easy. The same could be said of pthreads in C versus Java threads on a *nix box (although pthreads is pretty straightforward). I stopped using C++, except for assemblies that really need features that aren't available in C#, a few years ago. Some game developers have done the same, but they are a tiny minority. The move towards multi-core systems can only encourage the adoption of modern languages.




Footnote: C# and Java are both far behind academic languages such as Haskell in terms of innovation, and haven't even caught up with LISP and Smalltalk in terms of features. I'm not proposing a widespread move to the bleeding edge, just a step forwards to where the business world has been for a few years now.


Mood: relaxed
Music: None

Thursday, August 11, 2005

Heh, oops

I was brainstorming for a project I'm working on, and came up with a nifty idea... researched it, and it turned out to be NP=Complete, meaning that there is no way to determine when a solution can be found, or even if there is one (I don't believe the NC Complex=NC Complete arguments). Unfortunate for a routine that could be initiated by any user.... fortunately, a simpler version of the same thing runs in around 200 cycles. It's amazing what trouble overthinking can get you into!
Mood: accomplished
Music: None

Bad science joke!

Heisenberg was driving down the Autobahn whereupon he was pulled over by a policeman. The policeman asked, "Do you know how fast you were going back there?
Heisenberg replied, "No, but I know where I am."
Mood: tired
Music: None

Tuesday, August 9, 2005

Feeling better

So I'm feeling much better today. My fever broke around 10pm last night, and while weak, I more or less instantly felt much less like a corpse.


World of Warcraft is going quite well. I changed server (to play with a coworker), and levelled Wydgette, my gnomish Warlock, to 7 in about three hours. I simply did every quest I could find. I haven't died yet, so the ghost system is still a mystery to me. I was actually wondering how some of the corpses I found in the newbie areas managed to get themselves killed; I could take 2-4 newbie mobs at a time, and escape if things got bad. I'm also known for glacial levelling speeds in MMOs, and for not having the strongest play in the world. Ah well - maybe I'll last more than 10 minutes in PvP in WOW!


Work is going better. We moved our servers to the new office (hence the downtime - New Edge messed up the line move), and everything is working smoothly now. We've landed a bunch of really big contracts recently, and when they finally start paying us (cheap bastards!), the money problems should be over for a while. The IRS are paid off (at work - I still owe them some cash), we've cut our costs substantially - so I'm pretty sanguine about the future.


Back to the Code Mines for me....


Mood: relaxed
Music: Dio - Holy Diver

Monday, August 8, 2005

Various

I have a fever of 99.8F today. It sucks.


I've picked up World of Warcraft, and am playing around with a gnome warlock named Wydget. 5 levels in two hours was fun, and I think I could really get into this game! Everyone was really friendly, which is nice.


I put a new drive in MythTV, and it has a good 70 hours of recording capacity again. Woot. Very smooth with JFS on the drive, too; latency for large AV files seems much better than ReiserFS was.


Mood: grumpy
Music: None