In any game with enemies, these enemies need to be able to think a bit. Even just following and chasing after the player is a rudimentary form of AI but needed if these enemies are going to be impose even the teeniest bit of danger. So for a first level, what exactly should the goals be for the AI of the first enemies and how would this be done?
As stated before, we need to get these things moving. The simplest way is to just give the enemies the location of the player and constantly move the enemies to that location. The problem with this is two fold: first its prone to cause unwanted behavior and second its cheap in a sense. The second problem is the easiest to explain. By just giving the location of the player, the player has no way of evading enemies and there is no counterplay leading to more unfun enemies to face. The first problem is a lot more complex.
By just leading enemies to the player, the player might employ tactics or abuse this simplistic AI. For instance, these kinds of AI can be tricked into either killing themselves or getting themselves trapped as they have no sense of what is around them. Additionally, if enemies have collision with one another, they can often be fighting one another leading to quite unpleasant visuals and an equally unpleasant experience. So, how do we rectify this?
The easiest way to navigate around terrain is by letting a computer calculate a path around the terrain. The most common approach is through an algorithm called A* Pathfinding where you divide an area into a grid and find the shortest path to your target. Parts of this graph is marked as untraversable due to terrain and thus, terrain is taken into account. Now, for multiple enemies and a constantly moving player, this path needs to be calculated repeatedly and for every enemy. As you can imagine, this can be an expensive and slow process.
Programming such a method to be quicker would require having each enemy calculate their paths in different threads and do them in parallel. Due to an unwillingness to dive into such complexities, I elected to stick with a single thread computation and instead invoke the calculations at set intervals. Additionally, I combined this pathfinding with another form called context-based steering in order to switch between the two. What is context-based steering? It's the little lines you see radiating from the enemies. Essentially, to give your enemies true awareness of surroundings, you need to let them be able to, in a sense, see around themselves. These rays do that for them and with the information gathered, they can weigh the probabilities of hitting something if they go in a certain direction and course correct when needed. The beauty of this is that it doesn't need to calculate an entire path like A* pathfinding. All it needs to do is find a direction. Thus, if there are enemies around or terrain, it's easier to calculate a path this way rather than trying to recreate the grid in real time to account for other entities. Another reason for this is that A* pathfinding can have troubles with colliding into terrain and other entities, something context-based steering rectifies. Thus, we can calculate the shortest path then tune this path when needed with the steering.
Good question. I wanted to create simplistic enemies for the first level. That means, of course, slimes. Thus, they can be a bit mindless however, that includes in their attention spans. Two additions were made to emulate this behavior. The first is to give them an aggression range. If the player enters it, then they will attempt to follow and attack the player. However, with a slow speed, it lets the player run out of their range to drop their aggression. Thus, the player can approach them in various ways and leave at their own whim. The second addition is an extension of this. Instead of constantly tracking the player, we should check first to see if the enemies have line of sight to the player. If so, nothing will change. However, if we don't, the enemy will instead go to the last seen location of the player and stay there. Two small changes, but they make the enemies feel more alive and add more complexity that would otherwise exist. However, this is just movement and there are a number of other improvements that can be made which will be explored in the boss of the first level.