Background Level Loading
Question submitted by (17 November 1999)
|Return to The Archives|
I'm just a newbie with 3d graphics engine development, but i am trying to
do one special thing with my game engine that no one else (that i've heard
of) has done before. I call it 'background loading'. I want to be able to
load the 'next' approaching level of a world as the player in the game is
approaching it. For instance: what Half-Life and Quake2 do... but without
the damm 10-30 second wait for loading).
Many say this is impossible. I think everything is impossible until it has been done eventually by someone.
My graphics engine deals with Quake 1/2/3, HL, Hexen, etc... .MAP files. (there is no BSP information) I'm looking at using Octree-based portals. Any ideas on how to 'background load' a level with NO wait time? Another thing that sparked my interest in this was the mention of the new GeForce cards that will be out on the market soon enough. (More free CPU power to background load)
So far, when the player approaches a point in the next level, i think i might run a thread that loads more MAP information into the brush/vertex lists. But when i run this thread, i want the loading to be slow enough to 'divy-out' enough processing power to the actual rendering engine so things don't slow down...
I guess this might be more of a question of how to work with threads, but i also want to know if you experts have any other advice or ideas on how to 'background load' a level with NO wait time. Thanks for any help,
It's quite possible. Though, in most cases there will always be SOME
affect on the frame rate simply because IDE drives steal a lot of
Consider just about any flight simulator. They don't stop and say "loading next continent, please wait." :) Having just released a flight simulator, I can say that you might wish to avoid loading in a separate thread. Simply put the loading in the main game loop, loading little bits and pieces at a time.
In any case, you'll need to be able to load a little, render a frame, and load a little more. You can temper the amount you load by only loading... say... 4096 bytes at a time (ideally, the size of a single cluster). This way, you get as much data in a chunk as you can without suffering a lot of thrashing for fragmented files.
You might also determine that 50ms is the longest you're willing to give each load cycle. With this, you can keep a running average as to how long it takes to load each chunk, and decide if you have time to read another chunk before your 50ms runs out. Then simply call this timed loader once every second. If you can acheive this, you'll drop a 20FPS frame rate down to 19FPS (I doubt few people will ever notice this.)
To aid in the success of this, you'll need to store your data linearly and as tightly packed as possible. And remember, it's almost always faster to load/decompress than to load the whole amount of data from disk (depending on the decompression, of course.)
Once you have all of this working, you'll need to find some way to make sure that by the time you need the data for the next level, it's already loaded. But this is application specific, so I can't really help very much here.
Response provided by Paul Nettle
This article was originally an entry in flipCode's Fountain of Knowledge, an open Question and Answer column that no longer exists.