0

So I am working on adding entities in a game I am working on, I am wondering what the best way to structure enemy AI would be.

I have an entity Object with all of the usual functions built, and currently I am controlling what the entity does with two functions

entity.prototype.runMeleeAI = function(){
//makes the enemy make melee attacks
}

entity.prototype.runRangedAI = function(){
//makes the enemy make ranged attacks
}

I switch between which one of the functions runs with a property from whatever type of entity it is, so for example

const entityTypes = {
"slime":{ 
"AiType": "ranged"
}}

However, I am wondering how I should manage it if I want an entity to have an AI that is different from those two types, should I just create a new function, eg

entity.prototype.runDashAi = function(){
//do stuff
}

entity.prototype.runBossAI = function(){
//do stuff
}

Then if I wanted a special AI for an entity I could set it to be one of those

Or is there a better way to structure this? I want to have lots of different AI types that will only be used for one type of entity

Should I write the AI functions in separate files and then pass them on the entity object? or is there an entire way to do this i am not thinking of

Dr. Slate
  • 31
  • 4

1 Answers1

0

If you're not familiar with it, do some research on inheritance and polymorphism; the Wikipedia article on polymorphism looks "ok", but this SO question is probably a better starter: What is the main difference between Inheritance and Polymorphism?

Basically your AI functions control entities - of which there will be many variations; to do that all you need is some level of compatibility between the entities and the AI functions. Inheritance would let you do that - simply code a base entity type that all the AI functions can work with, like LandVehicleEnemy, and make specific enemies that inherit off that.

Here's some pseudo code:

class LandVehicleEnemy{ ... }  //  can move X-Y
class FlyingVehicleEnemy{ ... }  // can move X-Y-Z

class JeepEnemy : LandVehicleEnemy{ ... }
class TankEnemy : LandVehicleEnemy{ ... }
class GiantCowWithLaserEyesEnemy : LandVehicleEnemy{ ... }

You may even have differences at the individual enemy level (Jeep vs Tank vs Giant-Cow-With-Laser-Eyes), one workable approach there might be to have the AI functions use attributes declared at the base level, but defined at the enemy level, e.g.:

class LandVehicleEnemy{ 
  int AttackSpeed = 100;
}

class JeepEnemy : LandVehicleEnemy{ 
  // int AttackSpeed - not set, use base value.
}

class GiantCowWithLaserEyesEnemy : LandVehicleEnemy{ 
  int AttackSpeed = 100000;
}

You'll need to think about that carefully as part of your design - the number of entities and the amount of variation between them; the trick is to make your design flexible enough without making it overly complicated.

Lastly, in addition to inheritance is using interfaces (contracts). That works well for me in the OO-friendly land that is C#, my javascript knowledge is very dated. This might give you some insights: Does JavaScript have the interface type (such as Java's 'interface')?

Adrian K
  • 9,880
  • 3
  • 33
  • 59