Jump to content
  • Advertisement
Sign in to follow this  
whitee115

object management for persistent games

This topic is 4828 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

If one is creating a persistent world with potentially thousands or tens of thousands of "objects" in it (where object = cherry, character, car, building, planet etc), I imagine it's not wise to keep all of these object instances in memory at once. Is there a general knowledge about how to manage the objects in a persistent world, ie an object buffer which brings the info about objects in from disk/database as needed? Im trying to figure out where the tradeoff should be. on the one hand it seems unscalable to keep all object instances in memory at all times. But on the other hand, if they are not all kept permanently in memory, your code cant keep memory references to object instances, because they may not be in memory anymore. Rather, everytime you need to reference a game object, you need to ask the object manager to give you the (new) reference to the object (based on object ID). But this also seems inefficient- to query the object manager and search through the list of in-memory objects EVERY time you need a reference to the instance? Is there some compromise im not thinking of?

Share this post


Link to post
Share on other sites
Advertisement
This is achieved through streaming the level data from the disk. If you have some kind of portal system then as the player nears a portal then the level data is loaded from the disk - once the player moves inside that portal the previous portal state is saved to the disk.

Using this you can create very large seamless worlds with no waiting time in-between areas.

If you've ever heard of Jak & Daxter (PS2) they do the same thing and blend the different portals together with a combination of LOD and overlapping portal geometry (geometry that exists in both portals) and the only loading time is at the very beginning (and possibly during a few occasional cutscenes).

Assuming you know which portal and object resides in then you first query which portal is currently loaded and then query for the object itself.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
This is achieved through streaming the level data from the disk. If you have some kind of portal system then as the player nears a portal then the level data is loaded from the disk - once the player moves inside that portal the previous portal state is saved to the disk.


Would this extend to a multiplayer online style of game?
What im dealing with is a virtual world that consists of a set of gameobjects and discrete locations (think of a mud). Each gameobject and each location has member variables indicating
a) the id of the gameobject or location it is contained by
b) a list of the gameobjects and locations it contains
This information establishes the logical "structure" of the world.

I assume I cant keep every object in memory, for scalability reasons. So my initial thought was to create an object manager with a buffer that holds , lets say, 100 gameobject instances at a time. Any time a function needs to get info about or operate on a gameobject, it calls ObjectManager.GetGameObject(objectid)

That function would either
a) return a reference to the object if it is already in memory, or
b) go to disk/database and load it into the buffer (replacing an existing gameobject in the buffer if it is full), then return the ref.

However, this means that every time any method needs a ref to a gameobject, it must query the manager. (It cant rely on "old" references which may no longer be valid because the manager decided to kick it out of the buffer)

This is going to lead to a lot of queries to the manager, because some game processes call several functions, going by objectid, not by reference - so each of those functions would have to call the manager to get a ref to the gameobject with the given id

Im wondering if the resulting processing overhead from repeatedly querying the manager, searching through the in-memory list, and frequently loading from storage is just as much of a problem as the scalability of keeping them all in memory

Share this post


Link to post
Share on other sites
So you're asking what to do, when address of an object turns invalid, as data is streamed out and in. Maybe you could access them trough something like "handles". This handle would hold the pointer to your in-out-streamed object. You would have a thousand references to this single handle troughout your code, and your game object would always be accessed trough it. Now when your objectmanager reloads something, it would just need to update the address to this single place.

Share this post


Link to post
Share on other sites
Quote:
Original post by JanT
So you're asking what to do, when address of an object turns invalid, as data is streamed out and in. Maybe you could access them trough something like "handles". This handle would hold the pointer to your in-out-streamed object. You would have a thousand references to this single handle troughout your code, and your game object would always be accessed trough it. Now when your objectmanager reloads something, it would just need to update the address to this single place.



Im not 100% sure I understand handles yet. I understand the concept of obj manager associating handles with an object - so when you have a handle, and you want to mes with the object, I assume you have to call ObjectManager.GetObject(handle) -

But since now you are searching through the list of all objects every time you want to mess with an object, doesnt that add a lot of processing overhead? With a sorted list youve got O(logn), but considering the potential frequency it seems like a lot to me.

Share this post


Link to post
Share on other sites
Half-life 2 use a 32 bit handle, where 16 bits refer to the index of the entity within a large entity array, and the remaining 16 bits are a serial number. By having one component act as an index you get pretty much the fastest 'lookup' you can get, at the expense of having a large entity array allocated.

Every entity exists in this array, and therefor has a handle from the start. Other objects are free to get this handle from the object, and the handle is networkable, since the game is set up so that the entity in certain slots of the array are consistant on server and client. When the object is deleted or otherwise removed, the serial number for that slot of the array is incremented, therefor rendering any existing handles to that old entity invalid. From the looks of it, it seems to be a pretty efficient and useful system.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrEvil
Half-life 2 use a 32 bit handle, where 16 bits refer to the index of the entity within a large entity array, and the remaining 16 bits are a serial number. By having one component act as an index you get pretty much the fastest 'lookup' you can get, at the expense of having a large entity array allocated.

Every entity exists in this array, and therefor has a handle from the start. Other objects are free to get this handle from the object, and the handle is networkable, since the game is set up so that the entity in certain slots of the array are consistant on server and client. When the object is deleted or otherwise removed, the serial number for that slot of the array is incremented, therefor rendering any existing handles to that old entity invalid. From the looks of it, it seems to be a pretty efficient and useful system.




so does this limit you to 2^16 = 65K entities existing at a given time?

Share this post


Link to post
Share on other sites
Quote:
Original post by whitee115
Quote:
Original post by DrEvil
Half-life 2 use a 32 bit handle, where 16 bits refer to the index of the entity within a large entity array, and the remaining 16 bits are a serial number. By having one component act as an index you get pretty much the fastest 'lookup' you can get, at the expense of having a large entity array allocated.

Every entity exists in this array, and therefor has a handle from the start. Other objects are free to get this handle from the object, and the handle is networkable, since the game is set up so that the entity in certain slots of the array are consistant on server and client. When the object is deleted or otherwise removed, the serial number for that slot of the array is incremented, therefor rendering any existing handles to that old entity invalid. From the looks of it, it seems to be a pretty efficient and useful system.




so does this limit you to 2^16 = 65K entities existing at a given time?


Yes, assuming they only have a single entity array.
It wouldn't be (overly) difficult to increase that number for next-gen hardware if that was necessary.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!