ArrayList, Hashtable, or ... for holding in-game-objects

Because a call to getEntities() has to consistently return the “current” list (eg. entities0); also, I want any entities spawned to receive a call to process() in that tick. I don’t really know if there’s a cleverer way of doing all this but it does work very simply and intuitively.

Cas :slight_smile:

Couldn’t you call process() as you spawn them, before adding them to the other list. Depends where you need them ordered, I suppose - my way they’ll be next to the entity that spawned them I presume?

I just tended to find that anything that monkeys with the order of things being spawned tends to produce strange unreproducible effects. So with the hard and fast rule “everything is processed in the order it was originally created”, everything always works, the same way.

I have a feeling you’re just trying to avoid calling .size() on the list in that loop for the sake of it :slight_smile:

Cas :slight_smile:

Surely this

for (int i = 0; i < entities0.size(); i ++) {
   Entity e = entities0.get(i);
   if (e.isActive()) {
      e.process();
   }
   if (e.isActive()) {
      entities1.add(e);
   }
}

can be ‘optimized’ to

for (int i = 0; i < entities0.size(); i ++) {
   Entity e = entities0.get(i);
   if (e.isActive()) {
      e.process();
      if (e.isActive()) {
         entities1.add(e);
      }
   }
}

Depending on the implementation of .isActive() this can make your logic up to 3000x faster.

Is isActive() supposed to try to resuscitate the entity before finally determining if it is inactive or not?! I don’t see when isActive() would not simply return a boolean variable.

It was a joke :frowning:

Not at all. I don’t think you’d mentioned the necessity to keep in spawned order, just to call process() on the spawned object and keep things in a consistent order. Therefore, adding to the current list seemed a wasted operation. I also like to keep away from changing list contents while iterating over them, even if the way you’re doing it here is safe.

I think this is what confused some people, after you provided the actual code.

What I do is not remove the Entity until after the loop terminates. In my Bag implementation, I set the index to null (my Iterable knows to skip nulls) and when the loop ends, I remove all nulls.

Riven’s small tweak is quite right, small slip of the curly brackets.

Cas :slight_smile:

My response too… :frowning:

princec, thank you for explaining.

Very interesting. So basically, the advantage is that you don’t call remove(). Also, it will keep it in the order game objects spawn.

Are you declaring entities1 at the same time with entities0, so you can add entities from other places/methods? Why not declare entities1 within every frame when you loop keeping it local? Is it to keep the capacity of array within ArrayList same as the list before?, so unless you add new objects somewhere else, the capacity of list would not have to increase? And to avoid instantiating every frame?

Yes. No need to keep allocating and resizing it.

Cas :slight_smile:

A small optimization to ArrayList.clear() that I thought of: Maybe not really clearing it like ByteBuffer? Yeah, you might want to clear out old references so the GC can get rid of them, but you can do this every x-th frame (maybe with a semi-random bias so the “true” clears don’t sync up). That would get rid of looping through all the data each frame just to get rid of it.

I see. I’m thinking how I can implement this in my code. Since I have separate ArrayLists for each type of game object, I would have to prepare same number of ArrayLists I have so that I can buffer all of them. My concern is the cost of having 2 ArrayLists per type of object(enemy, enemy bullets, player bullets, and item). It’s not that my program is going through a serious need of tuning, yet, but I’m trying to think of the best way. I just don’t want to loop too many unnecessary times when detecting collision. There will always be a lot of player’s/enemy’s bullets flying around.

I do think it’s a good idea to loop game objects by order of spawn especially if I decide to interact between same types of entities or if I was keeping all my entities in one list.

I keep all my entities in one big list, generally. Collision I do with a grid cell approach (Revenge, Droid Assault) or simple brute force (Titan Attacks, Ultratron). I do mirror certain parts of the list into sublists of types, eg. buildings, gidrahs; but only the “main” list need be “double-buffered” in this way.

Cas :slight_smile:

Shouldn’t an Object[] just be 64-bit references, so it’s just 8 bytes times the size of the array? I mean, my laptop has 4GB RAM, that’s enough room for 536 870 912 array elements… Even in just one megabyte you can store 131 072 elements, so you should NOT worry about memory usage. I agree with Cas, a double-buffered ArrayList is most likely the best solution.

Just to chip in, I use a tactic very similar to princec:

  1. Typed uniform grids for fast collision detection.
  2. A long (ordered) list with all entities in the game.

This list has delayed addition and removal of entities (stored in a single queue).
Entities will have their spawn method called when they have become part of the entity list.
Entities will have their cleanup method called when they are no longer part of the entity list.
Thus entities are spawned and removed in order.

Another benefit is that the list of entities is stable throughout physics computation.
It works well under the assumption that the game objects stay in the game for a long time (several iterations).
But of course all methods have drawbacks :slight_smile:

I used to use the same approach for all games, but I’m shifting towards more modular and individual designs.
As such my game engine is starting to more and more become a game library instead…

  • Scarzzurs

Yup, me too. If by entity you mean a game object that animates, moves and/or can disappear from the game world.

Doesn’t all the adding and removing game objects generate massive amounts of garbage? I’m trying to understand the discussion here, but have a hard time understanding why - performance wise - any of these constructions should be better than a simple array, e.g. I’m usually doing something like this:


int numberOfBullets = 10000;
Bullet[] bullets = new Bullet[numberOfBullets];

for (int i = 0; i < numberOfBullets; i++)
  bullets[i] = new Bullet();

[... snip ...]

public void update() {
for (int i = 0; i < numberOfBullets; i++)
   if (bullets[i].isActive())
      bullets[i].update();
}