• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Platformer AI: high performance, and in high numbers.

Zerb Games

Member
So I was wondering how I could make a lot of platformer AI in a room in an efficient manor. Ultimately I would like to have as many AI as possible in the room, but obviously there is limits. I'm hoping YYC helps. Anybody know how I could accomplish such a feat, assuming I didn't have the YYC (even though I do)? This is a zombie game so high numbers is fairly important, I'm looking for something around 100, but if it must go lower I'm fine with that. I'm more looking for algorithms, and examples. So please if you could give a little technical info, otherwise just pitching ideas from past experience is always helpful. Thanks!
 

NightFrost

Member
It is my understanding that pathfinding in platformers typically use a node list for expressing the routes with A* to quickly discover the least expensive path. (Basically close to what GM's motion planning grid does, but mp_grid node list is always... a grid.)
 
100 instances running shouldn't be too bad, depending on the platform. I've pushed my crappy laptop to running around 500 instances using various optimizing methods. A few points that will help keep things running efficiently:
  • Don't run your path finding for every instance every step. Spread it out as much as you can. They are zombies after all, and not too smart, so they don't need to react immediately to player changes.
  • On the same thought process, again, since they're zombies, they probably wouldn't be able to magically traverse through maze like areas to find the player. I would only have them path find if they are within a certain range of the player, can see/hear/smell them, or whatever.
  • If at all possible, abandon the built in collision system and try to rework it to an array/grid based collision system. It doesn't look quite as smooth, but in the project I mentioned above, I was able to double my number of instances by doing this.
  • Again, zombies, so they're likely just to bunch up and stumble into each other when grouped up instead of trying to push each other out of the way. It's way easier on the system to just have them ignore moving if there isn't room.
... About all I can think of at the moment. If I can find the project I mentioned, I can post it here so you can take a look at it. It is just a prototype, mind you, and the array collisions aren't perfect yet, but it would be a start.
 

Nux

GameMaker Staff
GameMaker Dev.
  • Don't run your path finding for every instance every step. Spread it out as much as you can. They are zombies after all, and not too smart, so they don't need to react immediately to player changes.
  • On the same thought process, again, since they're zombies, they probably wouldn't be able to magically traverse through maze like areas to find the player. I would only have them path find if they are within a certain range of the player, can see/hear/smell them, or whatever.
I second this ^

A thing I will add, though, is to check if a wall is between the player and zombie. If there isn't, then they player and zombie are clearly on the same plane (flat surface, or the player is directly above the zombie, but with no object between them; they are floating), so simply move the zombie in the direction of the player, by example, changing it's x/y coordinates.
Therefore, you're only calling a path finding algorithm (such as A*, or Dijkstra's Algorithm) whenever a tangible object is between the player and AI, and never when there's a clear path.
 
A

anomalous

Guest
Are you creating the level obstacles or is this procedural?
If its pre-made, you may be able to figure out good routes/waypoints at level start and never have to run pathfinding in play.

Certainly I would think running those is not something you can do every step, nor is it something you want to do often at all, with hundreds. Its very brute force.
Zombies are not smart, you may just want to start with far more simple AIs like ones that choose each step to move in a way they can, that gets them closer to the player.
I
Pathfinding using those algorithm also gets much slower (I recall) if you are running a large distance (many grids/nodes) since its just more to check.

AI may not even be the bottleneck at 100 enemies, it really depends on your game and design. It could be draw for all we know, that limits you.
It may be necessary to batch your enemy draw, see the tech blog about the OUYA, they turned a lot of things off before drawing their sprites (blend modes and alpha testing, etc.) enabling a much faster draw call. If your enemies are all at the same/similar depth, this should be easy to do.
 

NightFrost

Member
  • If at all possible, abandon the built in collision system and try to rework it to an array/grid based collision system. It doesn't look quite as smooth, but in the project I mentioned above, I was able to double my number of instances by doing this.
I haven't done any speed comparisons, but a platformer with ds grid based "collision mask map" is not much more complex to create than a sprite collision based system. I don't know what you mean with looking smooth, but pixel perfect collision is completely achievable with it too.
 

Zerb Games

Member
100 instances running shouldn't be too bad, depending on the platform. I've pushed my crappy laptop to running around 500 instances using various optimizing methods. A few points that will help keep things running efficiently:
  • Don't run your path finding for every instance every step. Spread it out as much as you can. They are zombies after all, and not too smart, so they don't need to react immediately to player changes.
  • On the same thought process, again, since they're zombies, they probably wouldn't be able to magically traverse through maze like areas to find the player. I would only have them path find if they are within a certain range of the player, can see/hear/smell them, or whatever.
  • If at all possible, abandon the built in collision system and try to rework it to an array/grid based collision system. It doesn't look quite as smooth, but in the project I mentioned above, I was able to double my number of instances by doing this.
  • Again, zombies, so they're likely just to bunch up and stumble into each other when grouped up instead of trying to push each other out of the way. It's way easier on the system to just have them ignore moving if there isn't room.
... About all I can think of at the moment. If I can find the project I mentioned, I can post it here so you can take a look at it. It is just a prototype, mind you, and the array collisions aren't perfect yet, but it would be a start.
Nice, is this an example project I can download?

Obviously shouldn't run many path finding checks, none the less thank you for your input. I was thinking about doing some global. update time systems, so I could individual zombies have different update times based off distance to player, then have a global.update_time so that zombies have a clamp so if the game begins to lag with a lot of zombies in the same place, I can either set there update time lower, or make a different state for them to follow.

"Within a certain range of the player, can see/hear/smell them...." That's a tremendous idea there sir, it had crossed my mind at one point, but I dropped it for some reason. Was prolly tired, idk, but I could probably make there state different based off those sensory inputs. So perhaps standard ai is just base line "wander" towards the player. Then if they hear something it switches to a past paced, accurate path finding type deal, obviously would need to optimize.

As I mentioned previously I hate GameMaker default stuff. So I've already in part abandoned the default collision system, however I'm using box2d, and I haven't found a good way to do collision checking using array/grid based collisions. I'm sure it's possible, but I haven't tried it to be honest. Smooth is what I am going for.

Didn't plan on adding shoving, but definitely noted sir!

Thank you for your time!

I second this ^

A thing I will add, though, is to check if a wall is between the player and zombie. If there isn't, then they player and zombie are clearly on the same plane (flat surface, or the player is directly above the zombie, but with no object between them; they are floating), so simply move the zombie in the direction of the player, by example, changing it's x/y coordinates.
Therefore, you're only calling a path finding algorithm (such as A*, or Dijkstra's Algorithm) whenever a tangible object is between the player and AI, and never when there's a clear path.
I third that!

However, I do need to make animations and stuffs look nice. I'm using spine, so chunky x/y probably wouldn't do. I plan on adding a few states, so if the player isn't directly visible, I'd probably just change the state. D* is fair. Thank you for your time as well! I appreciate all the input so far!

Are you creating the level obstacles or is this procedural?
If its pre-made, you may be able to figure out good routes/waypoints at level start and never have to run pathfinding in play.

Certainly I would think running those is not something you can do every step, nor is it something you want to do often at all, with hundreds. Its very brute force.
Zombies are not smart, you may just want to start with far more simple AIs like ones that choose each step to move in a way they can, that gets them closer to the player.
I
Pathfinding using those algorithm also gets much slower (I recall) if you are running a large distance (many grids/nodes) since its just more to check.

AI may not even be the bottleneck at 100 enemies, it really depends on your game and design. It could be draw for all we know, that limits you.
It may be necessary to batch your enemy draw, see the tech blog about the OUYA, they turned a lot of things off before drawing their sprites (blend modes and alpha testing, etc.) enabling a much faster draw call. If your enemies are all at the same/similar depth, this should be easy to do.
Not procedural, but I do intend to add a level editor. I've always been kinda opposed to using objects for AI, but I'm sure there's a way to make nodes for the level on startup. Ahhh such tremendous ideas so far, thank you guys so much!

I'm sure I could find a happy medium between the two, somewhere in between creating nodes on startup, and having the zombies AI check for stuffs. I saw said tech blog. I may follow it soon, I already skimmed through it.

I haven't done any speed comparisons, but a platformer with ds grid based "collision mask map" is not much more complex to create than a sprite collision based system. I don't know what you mean with looking smooth, but pixel perfect collision is completely achievable with it too.
I have some people in the know that I am sure could help me out with a system like that. The box 2d things is a tad worrying though.

Thank you all!
 
Top