Animal Companion AI

About

I decided to create an AI because I have seen many AI in games and have always been impressed in the work that has been put into them. I wanted to try for myself to create an animal companion that would feel more alive to the player whilst also helping the player in a few ways. I decided to make this animal companion into a dog called 'Hundkött' - dogmeat, a funny reference to fallout. 

I wanted the dog AI to be able to:
  * Walk and follow naturally
  * Guide player to points of interest
  * Help in combat
  * Have a 'Normal' Idle
  * Have a unique personality quirk

Week #1

In the First week I set up and created the behaviour tree. I decided to use a behvaiour tree mostly due to being somewhat inexperienced with it. I had used a statemachine extensively throughout my studies at TGA, therefore I wanted to use something I had not personally used as much.  

basic behaviour tree and node class

the rough layout of the ai behaviour

I set up and planned the basic structure for the behaviour tree and started creating some of the basic nodes I would be using, such as walking to a point. 

Week #2

During this week I set up all the basic node structure of the tree, with the basic selectors and sequencers of the sturcture. some Nodes were still unfinished at this stage however things were taking shape.

initalMovement.mp4

Week #3

Now all nodes were in place and the real work could begin. I wanted to work as much as I could with the polishing of the movement as I could. This is because having a smooth and nice looking movement is very much required for having a natural looking AI. I also decided that instead of the dog following the player's position it would go to one of two points ahead of the player, whichever was closest. I wanted the dog to almost always to be seen which is why I let the AI always try to be ahead of the player.

followBlock.mp4
initialWander.mp4

Initial Wander behaviour

I first began with reworking the movement itself so that the AI would always walk forward and the AI would simply rotate in order to change direction.

 I felt as this would be the simplest way to do it and with that I could also create a wander behaviour were the AI would deviate from time to time in its intended direction to give a more natural look to the movement. 

I also wanted to make the dog match the speed of the player because having a companion that you have to constantly wait for is something that have always frustrated many players throughout the years. 

For this I calculated the movement delta of the player and set the speed accordingly. I also wanted the AI to be able to catch up to the player since I would have it moving about to different locations and then running back, like after a fight for example. Thusly I added a distance to the speed, so the further away from the target point the faster it would go. Not a crazy amount mind you but enough so that the AI could catch up to the player when far behind. 


improved wander.mp4

Wander behaviour is better and it follows player nicely

Week #4

During this week I began with fleshing out and improving the other actions of the AI, such as finding points of interest, Idle behaviour. 

The Idle behaviour I designed for was that the ai would either sit, sniff around or maybe find an item and "dig" for them. 

Initially I let the AI find a position near them when they were sniffing around, this would however lead to a custody battle between this node behaviour and the follow player behaviour. I let the follow behaviour less inclined to take over by increasing the distance the AI was allowed to be away from the player. The AI would however breakdance around the points they found and could walk too far away from the player. 

I first tried to use a wander method where the AI would change directions, however it proved unstable and after a lot of headache I used another method.The method I decided to use instead was fixed points in a half circle in front of the player which the AI would walk between at random. This made a more smooth "sniff" mode whilst making sure that the dog was always visible to the player. 

the walk points visualized when dog would engage "sniffing mode"

The digging was not too complicated, at an interval it would check if it managed to find an item it would then deliver it to the player. 

When calling the player to a point of interest I decided that the dog would only go toward the point if it was visible to the camera. This way the player would notice when the dog started to dart in another direction. I also made sure the dog didn't go to a point too far away. 

As a form of individual quirk I let the dog fetch an item the player dropped, as a way to appear wanting to play with the player or be helpful 'oh you dropped this, allow me to help' kind of thing or just playing fetch.

interest.mp4

dog starts to walk to object when visible to camera.

Week #5

At this point I started to attempt to further polish on what I already had made. 

I started allowing the AI to cheat behind the scenes, when the dog was out of sight it would turn slightly faster and would run faster to ensure that it would always catch up quickly to the player & feel like you always had your companion with you. It would also wait for a shorter amount of time at the interestpoints if you stopped looking at it. 

I mostly worked on movement trying to make it as smooth and natural with the time I had left. I made it so it would turn slightly faster depending on how much it had to turn, it would slow down upon coming closer to the target point, it would rotate first if the point was too close so the AI wouldn't start orbiting a point instead

Item fetch.mp4

dog found item whilst 'digging / sniffing'

Conclusion

So in the end, what did I learn?

This specialisation has taught me much about ai and its workflow. It was a tougher nut to crack than what I initially thought but it was a fun challenge. I would however have wanted it a bit more polished, especially its movement as it could've been improved despite how much time I tried to make it look organic I don't think I ever got it 'just right' as it looked robotic in some instances. 

I also realise it is a greater challenge to show emotion and give the AI a natural look without proper animations or look. the few animations I had were not really enough to convey what I would've wanted but alas, I am no animator and block-out animations was the best that I could do. 

Something I would do differently would be implementing some sort of state-behaviour tree hybrid, a statemachine with behaviour trees in it. This would give the the rigidity of a statemachine with some defined states such as, "follow" and "idle", whilst also using the strengths of a behaviour tree. I sort realised I wanted this as my nodes were having a custody battle over the dog but it was too late to refactor the entire system.

I also wish I would've scoped slightly smaller and focused more on the movement feeling natural as it is the big selling point for this AI. I also came to the realisation that, like many other things in programming AI could be infinitely improved. It could almost always look better and be improved. 

However in the end you must always make that assessment, "is it worth enough to the player". Will the player notice it, will this new function improve the player's thoughts about it. Much like how an artist would love to make its work more detailed one must question its worth. Does something that is always going to be far away have to be very detailed or can you get away with less detail.