Friday 7 September 2007

Why does id Tech 4 employ so much markup?

Something about Drift I didn't mention in my last post:

  • Terrain generation. A cuboid region can be created, and control points used to make outcrops of varying height and radius. Very easy to do, since the control point is added as a point entity with one extra field, 'radius'. I really want this to have dynamic level-of-detail in the form of quadtrees, and I have done some research into that, but it may be a while before I get round to implementing it.

I have just been rooting around the packages that come with Quake 4 and it seems that much of the resources in that game are plain-text. The level geometry is entirely in markup, which is largely human-readable and specifies everything from AI accessibility and entity dictionaries to brush planes and general decomposition (this appears to still be BSP but it's not clear). I say 'largely' human-readable, since sometimes all you are looking at is numbers. In the md5mesh format, there are tables of indices which are completely useless to a person, so exactly why has this move been made?

My first thought is machine independence. At load time, you simply parse the text into whatever is easiest for the machine to deal with, and these days that's not much of a speed hit. In the past, id has byteswapped structures when needed, and that's not a brilliant solution since it means machines engineered for architectures that require this byteswapping, will suffer a small performance hit. The solution I've gone for is to swap at the lowest level of the stream. This doesn't overcome the extra time needed, but it's as transparent as it's going to be. It's very nice to only care about these things once, and then be confident that all the upper layers will benefit.

I've been working on a way to serialise objects across the native filesystem, and I currently have a package file format, and cross-package references within the format. Each package provides a table of exports and imports, but the major problem is verifying that the data in the other package does indeed represent the original object that was pointed to. All I have right now is a unique number, which may become an MD5 hash or similar. Furthermore, is it really desirable to only allow the original object? The ability to 'supersede' the object with a modification would be interesting, but potentially unsafe. Adding an extra verification function to each class is a daunting task, but that might be the best option.

This weekend I plan to write a Quake 4 .map parser. I can already see how to parse the brushes. They are just a list of planes. Maybe that's why there's so much markup. To allow people like me to do things like that!

2 comments:

Anonymous said...

I think that it would be a good idea for you to include images of your project in your posts. This would help illustrate what you are talking about, especially to non-experts.

In fact, you might want to post the occasional video too - demonstrations of the destructable environments being environmentally destructed, dynamic lights lighting dynamically, etc. Embedded YouTube.com movies could be useful here.

- Tom

on epsilon said...

I agree that pictures and maybe videos would help, but I will wait till he right moment for those :).