best practices with managing sidescroller enemy movement?
So far Spryke has only had a few rudimentary enemies. These are either simplistic placeholders with very barebones code behind them, or else they are more complex but each have bespoke spaghetti code that won't be very reusable for future enemies. So I'm finally starting to build a proper enemy system now. My thinking was that I should make one sort of 'proto-enemy' that will be used for all the main enemies in the game. This proto-enemy would contain all the code and detectors needed to run, chase, jump, walk on ceilings, walk on walls, change animation, and all the other things that an enemy might do. Then when I want to make different enemy types that have different abilities, I would create an instance of this proto-enemy, give it a unique skin object, and turn some of these parameters and modules on/off as desired.
I started off thinking that my proto-enemy would have a bunch of detectors that help it navigate the environment. But once I started thinking through all the things it'd need to do, I realised that I'd need at least 14 detector objects for each instance of the enemy! For example, I want the enemies to be able to hop up a small step if they come to one. For this, it seems I'd need 3 different detectors - shown as red, purple and green in the pic (plus 3 more for the other side, so 6 in total)
http://bit.ly/35PFXdR
And I want the enemies to be able to jump over narrow steep gaps, drop down wide shallow gaps (like descending steps), and avoid wide deep gaps that would cause them to fall to their death. For this, 2 more detectors seem to be needed per side (so 4 in total):
http://bit.ly/2OE0nkp
And then there are separate little slope detectors for sloped ground, plus a detector that triggers the enemy to start chasing you if you touch it, plus a detector for sticking to the ceiling, for colliding with the player, etc. Having this many detectors per enemy seems crazy, both in terms of code complexity and in terms of performance. Which got me thinking that there must be a better way. Then it occured to me that you could probably do away with many of them, but instead place little invisible markers in the level that guide any enemy that collides with it. For example, one marker would signal that the enemy should jump X number of pixels, another marker would signal that a cliff has been reached and the enemy should turn around, and so on.
It also made me realise that there's probably a great deal that I haven't thought through properly, and that I should probably seek the advice of those who have more experience with this sort of thing.
So, how do you guys manage your enemy movement? Do you use detectors, or hidden markers? or perhaps do your enemies 'map out' their surroundings when they spawn once and store them somehow? How do you manage critters that can walk not just on the floor but on walls and/or ceiling? Do you use bouncing ball movement for enemies, or a custom fast-loop solution, or a combination of both, or something else? Do you use a single 'proto-enemy' object? Any other advice you'd give someone who's about to embark on making a system for enemies that have various abilities?
Thanks!