6

The question

Sorry about the title, could not seem to find a shorter/better description..

Here's the situation: I am making a simple game in which there is a big map (simple, but very big in size). There are also a lot of enemies on that map, but the action is exclusively around the main character (in a certain radius, which is a very small percentage of the map).

At each 'tick' (or step, or whatever you call it), there is a certain function called on each of those objects to determine their next move. For performance reasons, since I do not care about what happens outside of my scope of view (or at least, the very far away stuff), I'd like not to call that function on very foreign objects.

How can I manage these objects to make sure I always have a list of the nearby objects that is updated when I move around the map?

(I know it is tagged in C++, but any language will do - I'm not looking for code that much - It's more about the idea)


What I've already tried

I've tried a few alternatives:

  • Alternative 1: Separate my map in "zones" and store a list of enemies in each zone. The problem with that is what happens when I'm on edges of those zones and (worse) when I'm on a corner (4 different zones around me). Also, it's harder to make the enemies switch zones if I run from one zone to another (but I had figured out something which could work...)
  • Alternative 2: Scan the whole map and refresh the active enemies list each time I move x distance. That's a bit better since I don't have to worry abound bounds like Alternative 1, but I do have to scan the whole map each time.

I was now looking at Alternative 3, which is to mix those two solutions together.

However, I wanted to make sure there is not a more obvious solution.

Kevin
  • 74,910
  • 12
  • 133
  • 166
OneMore
  • 1,139
  • 2
  • 9
  • 19
  • 4
    IIRC, Minecraft uses alternative 1, so it certainly is a viable solution. It keeps more than one zone active at a time (maybe, say, an 8x8 square). This eliminates the problem where you're near the edge of a zone and there's an enemy next to you that's frozen in a non-active zone. – Kevin Dec 31 '12 at 18:20

3 Answers3

4

Store your enemies in a k-d tree and do a spatial range search every few iterations. You need, however, a fairly sophisticated implementation which supports entries moving around and re-balancing - sometimes called adaptive k-d tree.

edgar.holleis
  • 4,803
  • 2
  • 23
  • 27
  • 1
    Seems like I'll have some reading to do (I expected it). Thank you very much for your answer. – OneMore Dec 31 '12 at 18:34
2

Okay, if you could answer the following questions, I'm sure some of us could help with the right data structure and procedure. How big is the map?Actual dimensions? Tell us a bit about the density of enemies?How many of them on an average?I guess you are going to use a random number of enemies for each game, or perhaps increasing number of enemies for each level.In any case what is the maximum number of enemies that you plan to have?

It would be really good only if all the characters/enemies move around instead of just around the main character.Only that will make the game truly exciting.I trust you are going to use a lot of random numbers for movements, but try to see if you can come up with simple yet realistic algorithms for their movements, instead of fully relying on random movements.I have used random a bit and they definitely are no where interesting.Maybe you could move the ones very near to the main character slowly and the ones very far away quickly.You could increase the enemies speed and power as level increases.Try to make it as exciting as possible.You can try the Caesar III game and see how well the movements of people are, simple movement but really nice. Bottom line is think about how you are going to move the enemies, and as far as possible try to move all the enemies for each tick to make the game really exciting.

Aravind
  • 3,169
  • 3
  • 23
  • 37
  • I'm not sure how to answer the dimension question, but if the main character is 1x1, then the vision scope is about 20x20 and the whole map is more than 200x200 (so the vision scope is less than 1% of the map). The density of the enemies really depend on the part of the map you're in. It wouldn't be such a good measure to give you an average because the regions that contain less ennemies usually contain ennemies with a "better" AI (so more resources at each step). I don't have any maximum numbers of ennemies for now. Thank you for your answer. – OneMore Dec 31 '12 at 18:33
0

200x200 is not big. Foreach location, if it is in range, update enemy will work unless you plan on running it on a calculator, or want 1000s of updates per second.

Do not over engineer, keep it simple. Just make it easy to change if you need it.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • I usually stick by the KISS principle. However, I said 200x200 as an estimation. It's not tiled game so I can't just give you a size. But the action is definately localized in less than 1% of the map and the map is pretty much filed with objects/ennemies. That's what I wanted to get across. I cannot scan the whole map (thousands of ennemies and environment objects) at each update, because I do need to update the game very often (maybe not 1000x/s, but more than 30x/s for sure). But thanks for your answer. – OneMore Dec 31 '12 at 20:47
  • @OneMore The size you want to support does matter. Is it 200x200? 2000x2000? 20000x20000? 2 million x 2 million? 2 billion x 2 billion? Fundamentally different ways of dealing with the situation are optimal at different scales. – Yakk - Adam Nevraumont Dec 31 '12 at 21:30
  • It's not a tiled based game. I could make it 1x1 or 5000x5000 and it wouldn't make a single difference on how much stuff I can fit in or how my algorithms work (there's no actual "units" anyway). I'd just resize everything accordingly (my vision scope would be 0.0005x0.0005 "units" or whatever). My ennemies are not stored in a 2D matrix if that's what isn't clear. Thank you for your time, I'm going to go with the k-d tree suggested earlier. – OneMore Dec 31 '12 at 21:37