Hi,
I’m interested in how some of you more experienced game devs are organizing your scenes to track gameobjects. I’m making a 4x (Civ style) game with many, many gameobjects to keep track of.
A bit of background on how i’m doing things at the moment for the sake of discussion. Each of my objects in the scene are derived from an abstract monobehaviour class which I have called “GameEntity”. Each GameEntity has a unique integer ID. All of these GameEntities are added to a global Dictionary<ID, GameEntity> which I call the EntityTable. When it comes to a GameEntity (lets call it ‘Transport’) that can be a container for other GameEntities (lets call them ‘Troopers’) as well, there are a few ways I can think of to access my GameEntities with persistence and performance in mind.
Method 1 - Store a list of trooper IDs on the Transport GameEntity
This is how I have current set up my code. I find it intuitive, easy to understand, and save/load is simple. When I want to access a GameEnity, I just look it up in the global EntityTable by its unique ID number. When I save the Transport entity I just serialize the list of ids which represent the troopers currently stored in the transport. When I load the game I just deserialize the list. Simple, however I worry about performance with this method.
Method 2 - Store a list/array of trooper references on the Transport GameEnity
This is essentially the same as method one, except the list becomes a list of Trooper GameEntity references (i.e. List troopers = {EntityTable[0], EntityTable[1] etc.} <–pesudo code
I have done some testing with loops of millions of iterations and found that this way is up to 3 times quicker than method 1 in terms of accessing the trooper object directly from the list of references rather than looking up via the entityTable. The difficulty with this method is when it comes to persistence. Saving is easy enough, I just get the uniqueID for each trooper and serialize the ID list like i did in method 1. Loading is harder though. Basically you have to make sure you have already deserialized an entity and placed it in the entity table before you can add a reference to it in the Transport script. So you either have to be very careful about the order in which you deserialize things (objects that cannot contain other objects (Trooper) should be derserialized first, then the container objects (Transport) etc), or you can make two passes at all the entities when you deserialize. One pass to fill the entity table without building the internal reference list in all the ‘container’ (e.g Transport) entities, then another pass to build the internal reference lists.
So there’s my conundrum. What do you guys think is the best method? Is there an even better way than what I’m thinking above?
Would be great to hear your thoughts.
Aaron.