0
\$\begingroup\$

I was reading Game Engine Architecture by Jason Gregory

  1. So according to him, I should use an array of entities, and arrays for each property, such as an array gameObjectsPosition, gameObjectsHealth... But in my case, the world is divided in a chunk grid. Each chunk have its own array (or for the moment vector but I plane to change that) of entities (game objects). Then, what should I do? Create a single array containing all entities positions wherever there are (and so one for health, level, orientations, dimensions...), or create the property specific arrays in each chunk?

  2. Then how to process these property arrays? I mean, for each dynamic entity, I could update dimensions, sizes and health or I could for each property update each entity. Example:

     UpdateWorld() {
         for each entity in dynamicEntities
              entity.updatePosition()
              entity.updateHealth()
              entity.updateDimensions()
              entity.updateMesh()
     }
    
     UpdateWorld() {
         for each entity in dynamicEntities
              entity.updatePosition()
         for each entity in dynamicEntities
              entity.updateHealth()
         for each entity in dynamicEntities
              entity.updateDimensions()
         for each entity in dynamicEntities
              entity.updateMesh()
     }
    
  3. How to handle sizes for each chunk? That'd mean each chunk have an array with MAX_ENT_PER_CHUNK (say in my example 1024), and then if a chunk have 24 entities there would be 1000 entities useless. Also, I can't use more than 1024 entities. I could use pointers, but then the CPU cache would hit a lot of misses.

  4. How to handle IDs? If I have an array of entities I need to use IDs. I can use macro SID has specified in the book, but the IDs are not ordinals (they may not begin at 0)

\$\endgroup\$
1
\$\begingroup\$

Try not to take the stuff you read in books too literally and apply concepts only where you think they really fit rather than just because you are trying to follow some pattern.

In my case I design my entities to have properties based on what makes logical sense.

I would not loop through every object in this manner because doing so per frame will get very costly very quickly. Instead look at using a component based event driven design for your code. When some condition is met (event occurs) on an entity update it.

You could event have different events resulting in different changes. So for example a "collision event" might result in a health drop but also may result in a position change.

Also I keep telling people this but: stop using arrays where you don't know how many things you have in a collection.

If I do this ...

var x = new Entity[1000];

The compiler will go and allocate me 1000 Entities worth of ram, but unless I definitely need 1000 Entities of ram right now this is a pointless waste of time and system resource. Use Lists or Dictionaries instead as their dynamic size means your code will only use the resources it needs.

\$\endgroup\$
  • \$\begingroup\$ Thank you! Maybe for static entities a vector and dynamic entities an array (there are to be less dynamic entities)? And about looping this is how I do it: for static entities, they are updated according to their LOD (each entity have a mesh for each each LOD index, a 1 to 10 int) or rather their chunk's LOD. When a chunk's LOD change, then its entities are updated in consequence. But if it is the same then we do nothing. Also, for dynamic entities I am forced to loop them on each update since they position can be updated according to the physics \$\endgroup\$ – Vinz243 Feb 22 '15 at 10:38
  • \$\begingroup\$ I think you're missing some of the point of my advice here ... you are making a potentially large number wasteful calls every frame when you may not need to which will limit the performance of your game due to the evaluation of a wasteful call chain. you should not make a single call on anything unless you have determined that there is a reason to do so. \$\endgroup\$ – War Feb 22 '15 at 11:37
  • \$\begingroup\$ I understand that but dynamic entities are subject to gravity. That's why every entity update function fetch its position by asking the physics engine and then update its position on the screen. But the map should contain a minimum amount of dynamic entities which BTW are not always loaded (distance from camera) \$\endgroup\$ – Vinz243 Feb 22 '15 at 11:57
  • \$\begingroup\$ Static sizes would be used to performance goals. Not dinamic allocations an other stuff. @Wardy given a good approach, using component based architecture where each entity register itself to participated in next loop update. \$\endgroup\$ – heat Feb 24 '15 at 16:51
1
\$\begingroup\$
  1. The code should serve the software engineer. Not the other way around.
  2. The code should be written in the most intuitive and simple way it can be written (but not simpler).
  3. Do not take advice unless you understand who it's intended for and what it's intended to resolve.

You are wearing a very uncomfortable pair of shoes because someone said so but do you understand why it was suggested in the first place, vs a dynamic array of Entity instances with data members like most moden oop programmers would write? It is there for very specific performance concerns that are unrealistic for most modern indie games.

You should ask yourself why you are doing things this way precisely. What do you wish to accomplish by following these guidelines? There is no point in moving away from the simple tested concept of a dynamic array (read Vector C++) or Entity instances with data members and methods relevant to those entities.

There is not one needed advantage that you pointed out for having an array for each property. It does not make any sense if you are an indie and not encountering some mysterious performance issues that you think you'll resolve by reducing the amount of cache misses you get.

In fact, the cache is pretty big nowadays. If you only access relevant entities at any specific time then it's likely you'll have plenty of cache to contain their data. Besides even if you do need to access memory, it is unlikely that will greatly reduce performance. Run some benchmarks and realize what you are so bent on achieving by writing less readable, and harder to maintain code, is possibly not worth your precious time. What do you actually want to make?

If we don't know what is the X you want to get, we can't understand why you wish to Y when it's clearly inferior and questionable for a lot of situations.

\$\endgroup\$
  • \$\begingroup\$ So to recap: I should use vector or list, is that this? What about question 4) ? \$\endgroup\$ – Vinz243 Feb 22 '15 at 21:16
  • \$\begingroup\$ I wouldn't use a list. A vector is fine. You should have a goal and write the code to best suit that purpose. If you are just writing code for the sake of writing code with no clear purpose in mind, there is no way to decide if the code is up to par because there is no scale to measure it by. \$\endgroup\$ – wolfdawn Feb 23 '15 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.