Resource Cache Design

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Resource Cache Design

      I have been reading 'Game Coding Complete', and the design of the resource cache seems to load the entire resource into a block of memory. This is fine, but then when using the resource you are also creating another object (texture or game node for example) using the same data from the memory stream.

      Isn't this duplicating the data meaning you have two sets of mostly the same information? It doesn't seem very efficient. Ok, I understand that for textures it can sit in video memory, but that may not be true for other resources. Is there a reason why the resource manager shouldn't directly create the texture/mesh object etc?

      Also, assuming you have a lot of game objects (for example nodes in a scene graph), do these objects also need their own cache and temporary file area? Especially if you are dealing with an open-environment game like an MMORPG.

      Thanks for any clarification!
    • I'm not *too* keen on how to do resource handing efficiently since I've never programmed a complete game, but this is just a design off the top of my head. For things that can reside in and be used from system memory, you could use some pointer magic and decent class design to wrap the raw resource data in a token/handle class of sorts that provides an interface the rest of your game uses to access/manipulate the resource data, thereby making things reference the data stored in the cache and eliminating the problem of duplicating data across system memory. You could have an abstract base class Resource that serves as an interface to the various types of resources your game uses (textures, sound, music, scripts, what have you), then classes derived Resource can specialize in accessing/manipulating the raw resource data. Your cache then stores Resource references/pointers. When your game requests a certain resource from the cache, if it finds the resource in the cache, it returns the Resource reference/pointer. If it doesn't find it in the cache, you could use a factory or some similar pattern to handle the creation of the appropriate Resource object, which will know how to read the resource in from disk and store it in system memory. The factory returns this newly created Resource object to the Resource Cache, which stores it in its cache, then returns a reference/pointer to that Resource back to the subsystem that originally requested the resource.

      Just as an aside, in more general terms, a cache is nothing more than a mere holding place for frequently accessed data. The motivation for designing and using one is that fetching data from a cache is faster than fetching from its original source, assuming what you want is in the cache. In the case of this resource cache, you're putting things in system memory so you don't pay the penalty of always having to hit the disk just to get to your resources (which would bring any piece of software to its knees).

      I can't comment on things like an MMORPG since I have no experience with them, and I'm sure there are a lot of special considerations that go into the software design of such games.
    • One of the tricks used in professional game development is to have an external tool process raw resources into platform dependant, ready to use data. When the resource cache loads the resources, it may use a small temporary buffer to do the reading and maybe some decompression but the ready to use data should wind up right in the memory space it belongs - video ram, system ram, whatever.

      On top of that, the resource cache is smart enough to monitor CPU load and have a list of resources that are likely candidates to be used in the near future - this lets the resource cache bring in data when there is plenty of time to do it.

      On top of THAT, the resource cache and even world editor should have cache monitors that can warn developers if they are in danger of overloading the resource cache in any given area.

      This is a complicated, expensive design that could use an entire book to explain properly - so the version you see in the book, like many of the technologies explained therein, is really just the tip of the iceberg.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Hi,

      Thanks for the reply. So, when you talk about having it in a 'ready to use' data format, are you talking about streaming directly into a class object? I have seen this mentioned in previous game texts, but with virtual pointers and such it seemed a little risky to me.

      If you are talking about something else, could you explain how the resource goes from being a block of data in memory to being a class object, and what the interaction would be? I think this is where I am a little confused.

      Thanks!
    • When I say ready to use, I just mean it needs no further tweaking, decompression, reformatting, etc. in order for it to be used by whatever is going to use it - graphics chip, audio board, AI class, etc.

      As far as streaming it into a class object - that's more of a high level discussion that really doesn't effect the resource cache - which is at its simplest level a database of stuff that has unique identifiers. What happens after it gets loaded is more of a game architecture discussion.

      For that - look up the section of the book that talks about game application, logic, and view architecture. I think it's chapter 3....
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Thanks, again for the reply.

      So, loading a resource such as a JPG it would be up to the resource manager to do the decompression of the image into a format the graphics card could use (RGBA)? Either that, or you would store it as an immediately accessible format such as BMP or DDS?
    • Now you got the idea - it totally depends on your renderer - if you were doing a PS2/XBOX game you would actually create two resource builds, one for each platform, that stored the texture in as close to the native format as possible - which in the XBOX might very well be DDS.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Hi, couple more questions for you if you don't mind. In your example on page 214 you are getting a bitmap using the rescache->get() function. I assume this must be used straight away and that the pointer cannot be saved and used again, since technically that resource could be freed at any time by the resource cache when it is called again?

      Also, if you are working in a multi-threaded environment then you must place a lock around the get() and the using of the resource to ensure no other threads call the cache manager and have it accidentally free the resource you are reading from?

      Thanks again... and congratulations again on a great book.
    • You got it exactly right.

      You could probably redesign the cache to lock some resources in place, avoiding the expensive multi-threading locks - I'm sure that is a common thing to do.

      Something I think deserves mentioning - I think having a fine degree of control over the cache is very important - even allowing default resources to be used in cases when they can't be swapped in - or scheduling specific convenient moments to swap in a big group of resources - like when you drive through a tunnel or ride in an elevator. This provides a seamless environment with nothing getting in the way of the player.

      Very very hard to do though....and almost as hard on designers as it is on programmers.
      Mr.Mike
      Author, Programmer, Brewer, Patriot