|
|
Hi Vast =)
I think the solution here is to seperate between resources, resource data, and entities.
Resources include bitmaps, prefab meshes, sounds, and the likes. Entities have pointers to resources, and may request resources by a resource name (i.e. a filename within your project directory for example). Note that since you don't know what entity still keeps pointers to any resource, you should never delete resources.
This is a problem though for many resources, since resources may take up lots of memory. However, as I mentioned before, you may seperate resources and their data. For example, a bitmap resource consists of a string name, and a pointer to the bitmap pixels. Whenever the bitmap resource wasn't used for quite some time, free the data pointer, but keep the actual bitmap object. This should be done internally within the rendering system. Then - either if the bitmap resource is requested again, or if it is simply used for rendering - load up the bitmap data from file again. You might also add a "never unload" flag to indicate important resources, such as menu bitmaps. Finally, since you also kind-of seperated resources, rendering and logics, you may use (and also need to use) a seperate thread to handle resource reloading.
This method results in using just a little memory for each resource loaded - about 100KB for 1000 resources. Additional memory only is required for resources that currently are used.
Futhermore, the approach both allows for easy loading and usage of resources in code and in level data - just load once and then use. You need not worry about resource unloading / reloading anymore.
Meshes also are implemented as a similiar resource. Here, you may free all vertex and poly data whenever the mesh wasn't used for some time. This is also the solution to your "baking" question. Don't bake identical meshes, unless you somehow feel the need to waste memory. Rather, have just a small entity struct that owns a pointer to the static mesh resource within your rendering system. For rendering, the entity only specifies it wants to get this pointer rendered at its location.
With entities you may use the same scheme.
The first idea, though, would be to load up all entities at once, considering that your usual entity doesn't require too much memory, anyways (around 100 bytes are probably realistic here). This is about the way TES: Morrowind handles its huge world.
However, there are few cases where this is not feasible, for example if large data is associated with entities, such as collision meshes.
Yet, simply deleting all entities that are outside some range around the player gives you the same problems as deleting resources: What to do with pointers to these? You might hack around some bit, and perhaps use reference collecting pointers, but things will get ugly. Also consider gameplay critical entities. What if the freighter you should protect is cached out, alongside a lot of enemy pilots?
Consequently, you keep all entities alongside their name in memory, and handle larger entity data the same way as resource data: Only load on demand.
Another strategy to consider is to pack everything that is common about several entities into a static instance. This also is done in TES: Morrowind. There is just a single "Rock_17" class entity that describes how the rock looks, what collision mesh it has, and how it behaves in the game. Then, each instance of Rock_17 just points to the class entity, and only provides its own rotation and location.
Finally, yet another idea I had was to allow for comlete object unloading and reloading by not using pointers. Instead I wrote a replacement system where instead of accessing objects by a pointer, they were accessed by some symbolic name - containing both a file name, and an object identifier. Whenever an object was not found by its name, it was loaded from disk, using the specified file and id. While this system was really great in some aspects - you needn't worry about invalid pointers, or about storing and loading pointers within files - it also had a ugly drawback. Accessing objects via symbolic lookup takes ages.
I hope this helps a bit,
Cheers, - Wernaeh
|