Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing and retrieving references to unloaded objects in game world

I'm making an open-world single-player RPG in which the world is composed of mostly isolated regions, which for scalability are divided into sections. The world contains beings that interact with each other. Most beings will have references to other beings, possibly including beings in other regions. A class definition for being might look like

class Being {
    weak_ptr<Being> target;
    // other members
};

Of course, I need to be able to save and load the game state to and from disk. Now, I don't want to have all beings loaded at all times. I only want to load those beings that are near the player or, at worst, all the beings in the currently loaded region. What is a good strategy to accomplish this? Here are a couple of ideas I've tossed around so far.

  1. On disk, beings will store a unique identifier for each referenced being. As being A is loaded, if referenced being B has already been loaded, the pointer is simply set. If B is unloaded, it must also be loaded. The downside is that this could recursively load a lot of beings that might not be used directly.
  2. Instead of beings containing actual pointers, they'll contain identifiers. Then as the referenced beings are used (for instance, if a being needs to damage another target being), they'll be loaded only as needed. This complicates using the references and has the potential to cause more save/load operations, but it avoids loading unnecessary data.

Are there better alternatives to these options? I imagine this is a common problem, but I haven't been able to find related questions on SO.

like image 618
Jonathan Sharman Avatar asked Nov 11 '22 02:11

Jonathan Sharman


1 Answers

You could use something like the Flyweight Pattern to help you do this. Then each type of Being is really only loaded once (which can be done lazily as they're needed), and then each Being instance just contains instance-specific variables such as position, speed, etc.

If that's not enough of a savings, you could write an instance manager that has an API for requesting a reference-counted pointer to a Being. The reference object would notify the instance manager when it's destructed. This would make it easy for the reference manager to marshal Beings to and from disk as needed.

like image 70
gct Avatar answered Nov 14 '22 21:11

gct