Working with A.I in a rouguelike

I’m working on a procedurally generated rouguelike that’s similar to chocobo’s dungeon or legend of grimrock. It’s not aesthetically pleasing yet since I’m just experimenting with code while my concept artist works through sketches.

The levels essentially work like this:

  1. The Master, which is an empty, spawns the first tile, holds the limits for the tiles and walls and spawns the stairs to the next floor.
  2. The tiles spawn more of themselves, until a limit is reached, at which point the tiles are added to an array which represents a room.
  3. all penninsulas(tiles with 3 sides empty) spawn more tiles to form pathways until yet another limit is reached,and spawns a new tile for the next room.
    4.step 1 through 3 loop until a limit of tiles is reached, as declared by the master.
  4. walls surround the rooms and paths and then expand until another limit is reached, again as declared by the master.
  5. The floor tiles that make up the rooms are arranged into a new array. then one tile is picked at random to be the staircase to the next floor.

1445062--77852--$Screen Shot 2013-12-07 at 5.03.00 PM.png

it looks something like this when it’s finished loading

The next thing i’m working on is monster A.I.

The monsters essentially move like the monsters in most rouguelikes. When the player makes a move, so do the monsters. There are 3 things I’m trying to figure out.

1.How to get the monsters to begin doing this.(I’ve run into some problems doing this)
2. when the character moves one space to get adjacent to a monster, the monster should attack rather than move.
3.if there are more than one monster adjacent to the player, figuring out which attacks first.

do you guys have any ideas on how to accomplish these things? Any help would be appreciated.

How is your game setup behind the scenes?

In your instance I would make a monster manager that has a list of all the monsters in the level.
A top level ’ game manager ’ would control the overall game, so when the player ends turn, it switches to enemy movement and tells the monster manager to start the enemy turn.

Monster manager can then go through the list of monsters in the world and move/attack/etc as required.

If they all share simple AI the method could be contained in the monster manager, if you want different monsters to behave differently, have them all inherit from one base monster class and have a ‘ProcessTurn’ method in the monster class itself.
eg1. - Basic:

for each monster in all monsters
ProcessTurn(thisMonster)

eg2. - Monsters own AI

for each monster in all monsters
monster.ProcessTurn()

Within the process turn, you handle the decision making - to do that, simply put down on paper first what you want them to do (in priority order)
eg. Attack if next to player, otherwise if player within x range, move towards player, otherwise move randomly/patrol/stay in one spot etc

so you have something like

ProcessTurn(thisMonster)
- if next to player, AttackPlayer()
- else if player in sight range, MoveToPlayer()
- else PlayerNotNear() (or Idle(), Patrol() etc)

If you have the processturn within the monster script you can have a BaseMonsterClass with the method, then inheriting from it you can have MeleeMonster, RangedMonster, HitAndRunMonster etc, all overriding the ProcessTurn method with their own hierarchy (and implementation) of actions. That way the variable for each monster is of type ‘BaseMonsterClass’ so you can hold all the different types in one array but they will handle the ProcessTurn call their own way.

Hopefully that helps somewhat!

That makes sense. I’ll have to give that a try.

Have you ever played Castle of the Winds? It had a neat turn-based system. I believe it was based on each turn being a second, and the more you were loaded down, the slower you moved. And different actions would take more or less time.

You simply loop through all your entities, and see which ones get to act this second. Sort them based on Agility then Speed then Intelligence, etc, and once they act add the number of seconds their action took to know when they get to act again.

On a computer RPGs (as opposed to table-top), micro-turns are easy to do, and then you can get interesting situations where a player might need to drop loot to be fast enough to escape a fast monster. Or make powerful attacks actually take longer than regular attacks, etc.

That’s just a random suggestion, though. MickM’s advice makes sense. You may also want to make an AI_Action class that has a priority value so you can shift the order enemies attempt actions at run-time. Each type of action an enemy can take inherits from that, with a function that completes the action and another that calculates the current priority of that action. Injured or afraid enemies may try to escape rather than attack.

Basically I’m just saying look into “priority queues”. It’s a simple data structure, but might give you some more flexibility if you code it up using one from the start.

I’ve looked into generic lists and found some interesting things. My game deviates from Chocobos dungeon in the sense that monsters spawn every certain amount of steps, which makes using a list a little more difficult. How would you go about adding newly instantiated objects to a list.

Your game manager tracks when monsters need to be spawned, have a GO variable (eg. newSpawn) and save the instantiated object saved there, then just add that one to the list.

Something like

newSpawn= Instantiate(monsterToSpawn, positionToSpawnAt, Quaternion.identity);
listOfMonsters.Add(newSpawn);

Ok I see. Will give this a try. Thanks.