It's not something I've really brought forward very much, but DirectQ is probably the highest capacity engine there is. There have been a few bugs along the way to this position, and the most recent (making it impossible to complete warpc without cheating) were eradicated as recently as yesterday.
In a lot of places the limits have been raised all the way to infinity. When I say "infinity", I mean of course that there are practical limits such as how much RAM your PC or graphics card has. Another practical limit is 32767 leafs or nodes - because a signed short is used to store leaf/node indexes in the BSP format itself (with negative values indicating a leaf).
This has been achieved without requiring any user intervention at all. There is no need to set -heapsize when running DirectQ, no need to specify a server-side edicts limit yourself, no need to specify a particle count limit, and so on. The engine itself will look after all that nasty messy stuff, and you can just play the game without having to worry about it.
In addition, I don't just increase limits, where possible I remove them entirely and dynamically allocate as needed - sometimes one object at a time, sometimes in batches (where avoiding runtime overhead of many small dynamic allocations is desirable).
All of this is possible because of the memory architecture of DirectQ, which I said I was going to write a bit about. I'm not going to go into any deep technical discussion, but will describe the evolution of it a little bit, as well as how it works in more general terms.
The first release used the very same hunk/cache/zone architecture as classic ID Quake, with a slightly raised limit. From there it moved to removal of the cache and zone, and using a tagged heapblock system in a linked list. The upcoming 1.7 restores the cache and zone, removes the tagged heapblocks, and runs everything through the Windows API virtual memory system.
What this means is that I can reserve a pretty damn huge chunk of process memory at startup (currently about 1 GB) but not actually use any of it until I need to. This chunk is partitioned off into various pools, each of which are dedicated to a single allocation type. There is a pool for permanent objects, a pool for the current game, a pool for the current map, and so on. The size of these pools imposes an upper limit on memory available to the engine, but because it's only reserved memory - not actually used - this upper limit can be set quite high. The current map pool, for example, is set to 128 MB - as warpc only uses about 45 MB of that, it's not likely to be ever exceeded.
Cache memory is used exactly as it was in classic ID Quake - for storing objects that can be reused between maps, such as alias models and sounds. The system is vastly simplified however, and does provide for a very significant boost in loading speeds.
Zone memory is used for all other allocations, not just small strings. The Win32 Heap functions provide identical functionality to the classic ID Quake zone system but with all of the messing around with concatenating blocks moved back to the API rather than shoving ugliness in your face.
In addition, a lot of the objects that were previously stored in big static arrays have now been moved over to dynamic allocation as required. In this way, a more accurate count of how much memory is actually being used (and how much is needed) can be obtained.
The end result is a very flexible system that takes responsibility for ensuring that Quake has enough memory out of the players hands and puts it back to the engine - where it belongs. It's not portable, but then neither is Direct3D, so I'm not too concerned about that. What it is is a whole lot more player-friendly, and it also plays nicer with the underlying OS, giving a more solid and stable game overall.
Saturday, August 29, 2009
DirectQ Tech Notes
Posted by
mhquake
at
10:29 PM
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment