There are many different behaviour trees. Some that have been shown by teachers, some that are online done by people working on major titles. But they do basically the same thing by the looks of it. The AI will need a behaviour tree. So the first thing I’ll be doing is making a list of all the things the player will need to do. I’ll start with the bare minimum for combat (without capture the flag). The basic flow of the AI according the the brief is as follows:
- AI stands for a random count “Idle mode”
- After count is up, AI picks a random nav point and creates a path with A*
- The AI then walks the path and goes back to idle mode and this is repeated
- If the AI sees an enemy in any of these steps, it switches to attack mode
- In attack mode the AI will walk directly towards the enemy, shooting his gun
- If the AI kills the enemy, he will switch back to idle mode
- If the AI dies, he will switch do Die mode
- In die mode, the die animation will play, and then the AI will respawn and the process is repeated
To break down into smaller actions, the AI tree would look something like the following:
- Guard (selector)
- StandGuard -> complete
- WalkPath (check for enemies -> Attacking) -> complete
I may refine these even more but this is the basic tree I’ll be creating.
For these to work, they will need to be arranged in a way that the tree can choose which one in order of importance. The order would be:
- Is Dead? Do die sequence (first priority)
- Can see enemy? (do attack sequence)
- Has Guard time? (do Idle)
- Otherwise do roaming (pathfind mode)
To make this tree, I will first make a main “BehaviourNode” class. This will be what all nodes derive from.
From this, I’ll make a “CompositeBehaviourNode” class. This will be used as either sequences or selectors. Each will be assigned on the creation of the object in their constructor.
Finally, I’ll make an “ActionBehaviourNode” class that all my main actions will be derived from.
The reason I’ve decided on this approach, especially with keeping the selector and sequence in one class, is for simplicity’s sake. From this there ill be less code and also less files laying around. I am also concerned about me forgetting which is which.
The nodes will all have a method called “Execute”. This function takes in deltaTime for it’s measurement of time. It will also need to access the world some how. I plan to do this by referencing the Player in the constructor of each BehaviourNode. Normally the best practice for this sort of thing would be to use a “Puppet” type of object, and the player be derived from that, but in the case of this simple game, where there’s only 1 type of actor, I’m going to do it this way.
I strongly believe the best way to learn how to code is to jump in and do it, and then make mistakes so you can write it better again. That’s what school is for. I’m not going to be able to make the perfect behaviour tree no matter how hard I try.
Below is an attempt at a diagram of the structure of the tree if we implemented the capture the flag mode:
And here’s the class diagrams:
I’ll also need to create some sort of Blackboard class to communicate with each leaf node and also so the player knows when to die. I’ll probably use this also for decorations as I don’t plan on doing any decorator classes until I see a fantastic advantage to doing them. For now I just want a working tree so I understand the basic concept.
So on with the code!