7/24/2014 - Creature AI Part 2

Your chance to hear me complain

7/24/2014 - Creature AI Part 2

PostPosted by Railboy » Thu Jul 24, 2014 9:43 pm

The Creature AI upgrade stretch goal is now 100% complete. In addition to the behaviors I blogged about earlier we now have companions, stealth and behavior voting.

Companion AI

You can tame animals with their favorite food. If a creature sees you with their favorite food equipped they'll wait and watch you. If you manage to approach without scaring them - timid creatures will bolt if you do anything but crouch and move slowly - then you can tame them with a context skill. They'll eat the food and follow you around from that point on.

Tame.jpg

If any hostiles attack you, they'll attack the hostiles on your behalf unless they are Timid and spook. If they don't have hostile capabilities then they'll just follow you and look at things they find interesting. If the animal has at least average intelligence (the range is 'Stupid, Average, Smart') then you can instruct it to wait for you. But it will only wait as long as its short-term memory lasts.

The best part? None of this is hackey or kludgey - it's all done using the Motile script, two WIScripts (Tameable / Tamed) and a basic Skill script.

Stealth

Creatures can now 'hear' IAudible objects within their hearing range and 'see' IVisible objects within their view distance and field of view. IAudible / IVisible objects can influence the effectiveness of the creature's seeing and hearing by supplying multipliers for these ranges. So if a creature sees the Player (which is both an IAudible and an IVisible) and the player's combined stealth skills return a 0.5 multiplier on any creature's visible range, then the creature fails to see the player at any range greater than half its visual range. Separating the visual / audio makes it possible to mix and match stealth skills - Eg the Silent Stalker skill will decrease your audible range while the Hidden skill will decrease your visible range. And creatures who have bad eyesight can have great hearing & vice versa.

By design creatures can't identify anything based solely on sound, but they can hear just about anything including the rustling of leaves and bushes. If they turn to look at the source of the sound, then they can identify what it is.

Here's a top-down screenshot from Unity where I've turned on visible field of view / audible range for players & creatures:
Stealth.png

It's nothing fancy - there are some really amazingly sophisticated stealth engines out there - but it gets the job done. The only unanticipated downside of all this is that the stealth skills make it harder to train animals, since they have to see you holding the food and a narrowed field of view / reduced visible range makes it harder to get their attention. Not really sure how to fix that one.

Behavior Voting

To keep all these WIScripts (Timid, Aggressive, Hostile) from contradicting each other I've created an anonymous voting system. Each Creature has a CollectiveThought object - they can collectively vote on how to react to what they've seen. Whenever a Creature is informed that they've seen an item of interest, it loads it into its CollectiveThought and invokes its OnCollectiveThoughtStart action. Any WIScripts subscribed to that action can vote on how to react to it. It can also vote multiple times if it's really serious. Here's how the TImid script handles a CollectiveThought:

Code: Select all
namespace Frontiers.World
{
   public class Timid : WIScript {

      public Creature creature;

      public void OnInitialized ( )
      {
         creature = worlditem.Get<Creature> ( );
         creature.OnCollectiveThoughtStart += OnCollectiveThoughtStart;

         ...   
      }

      public void OnCollectiveThoughtStart ( )
      {
         IItemOfInterest itemOfInterest = creature.CurrentThought.CurrentItemOfInterest;
         switch (itemOfInterest.IOIType) {
         case ItemOfInterestType.Player:
         default:
            if (creature.IsFamiliarWith (Player.Local.ID)) {
               creature.CurrentThought.Vote = ItemOfInterestReaction.IgnoreIt;
            } else {
               if (Player.Local.IsCrouching) {
                  creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
               } else if (Player.Local.IsWalking) {
                  creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
                  creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
               } else if (Player.Local.IsSprinting) {
                  creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
                  creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
                  creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
               }
            }
            break;

         case ItemOfInterestType.Scenery:
            //scenery is things like rustling trees
            creature.CurrentThought.Vote = ItemOfInterestReaction.WatchIt;
            break;

         case ItemOfInterestType.WorldItem:
            if (creature.CurrentThought.CurrentItemOfInterest.worlditem.Is <Creature> () && !creature.Den.BelongsToPack (itemOfInterest.worlditem)) {
               creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
            } else if (itemOfInterest.worlditem.HasAtLeastOne (creature.Props.ThreateningScripts)) {
               creature.CurrentThought.Vote = ItemOfInterestReaction.FleeFromIt;
            }
            break;
         }
      }   
   ...
}



Unless the creature is familiar with the player - this is something the Tamed script is able to modify - the Timid script votes to flee. If the player is acting aggressively - standing or sprinting - it votes to flee multiple times.

And if the creature sees another creature that doesn't belong to its pack, it votes to flee. Or if it sees a WorldItem that has a script that it finds threatening (eg, Hostile or Fire) it flees. TL;DR - it flees.

But that doesn't mean that the eventual result will be 'FleeFromIt' because other WIScripts are getting in on the voting as well. If (say) I had a Starving script for creatures that hadn't eaten in a long, long time (I don't plan to include this but it's something modders could add) it might vote like this:

Code: Select all
namespace Frontiers.World
{
   public class Starving : WIScript {

      public Creature creature;   

      public FoodStuff ThingToEat;   

      public void OnInitialized ( )
      {
         creature = worlditem.Get<Creature> ( );
         creature.OnCollectiveThoughtStart += OnCollectiveThoughtStart;

         ...   
      }

      public void OnCollectiveThoughtStart ( )
      {
         FoodStuff foodStuff = null;
         IItemOfInterest itemOfInterest = creature.CurrentThought.CurrentItemOfInterest;
         //can we eat it?
         if (itemOfInterest.IOIType == ItemOfInterestType.WorldItem && itemOfInterest.worlditem.Is <FoodStuff> (out foodStuff)) {
            ThingToEat = foodStuff;
            //we can eat it! vote to eat it
            creature.CurrentThought.Vote = ItemOfInterestReaction.EatIt;
            if (Stacks.Can.Stack (foodStuff.StackName, creature.Props.FavoriteFood.StackName)) {
               //it's our favorite food! oh my god we HAVE to eat this
               creature.CurrentThought.Vote = ItemOfInterestReaction.EatIt;
            }
         } else if (ThingToEat != null) {
            //we don't care WHAT this new thing is, we have a thing to eat
            //ignore anything that's not the thing to eat
            creature.CurrentThought.Vote = ItemOfInterestReaction.IgnoreIt;
            creature.CurrentThought.Vote = ItemOfInterestReaction.IgnoreIt;   
            creature.CurrentThought.Vote = ItemOfInterestReaction.IgnoreIt;   
            creature.CurrentThought.Vote = ItemOfInterestReaction.IgnoreIt;   
            creature.CurrentThought.Vote = ItemOfInterestReaction.IgnoreIt;   
         }
      }

      ...

   }
}


If it sees its favorite food it'll try to eat it - and if anything else comes up while it's still trying to eat that food, it'll spam the votes with 'IgnoreIt' to keep its Timid nature from winning out. And at no point did I have to coordinate with the Timid script to make sure we don't contradict each other - the two scripts know nothing about one another.
Language is to the mind more than light is to the eye.
User avatar
Railboy
Developer
Developer
 
Posts: 1845
Joined: Mon Jul 15, 2013 10:46 pm
Location: Seattle, WA

Re: 7/24/2014 - Creature AI Part 2

PostPosted by yarnevk » Thu Jul 24, 2014 9:59 pm

CollectiveThought really should be called Neural AI, its what brains do is collect multiple conflicting inputs and take a fuzzy vote. Hope you figure out how to tame a stealthy wolf because I want one for my dog so we can go hunt wabbits.
yarnevk
Pathmaker
 
Posts: 178
Joined: Tue Sep 17, 2013 2:48 pm

Re: 7/24/2014 - Creature AI Part 2

PostPosted by Railboy » Thu Jul 24, 2014 10:05 pm

yarnevk wrote:CollectiveThought really should be called Neural AI, its what brains do is collect multiple conflicting inputs and take a fuzzy vote. Hope you figure out how to catch a stealthy wolf because I want one for my dog so we can go hunt wabbits.


I'm an amateur neural network buff and I think this is a little too simplistic to fit the bill. There's no feedback or reinforcement or anything like that. I'd say it qualifies as fuzzy logic though.
Language is to the mind more than light is to the eye.
User avatar
Railboy
Developer
Developer
 
Posts: 1845
Joined: Mon Jul 15, 2013 10:46 pm
Location: Seattle, WA

Re: 7/24/2014 - Creature AI Part 2

PostPosted by Starfia » Thu Jul 24, 2014 10:07 pm

Wow, lovely. This is the first I've really read about AI at all beyond the very most basic, and I might need that sometime. It's great to see anyone else's ideas at all.
User avatar
Starfia
Bard
Bard
 
Posts: 158
Joined: Thu Jul 18, 2013 5:57 am
Location: Bellingham, Washington

Re: 7/24/2014 - Creature AI Part 2

PostPosted by postnjam » Fri Jul 25, 2014 9:34 am

Rabbit friends? Welp. Time to name my guy Lennie.
User avatar
postnjam
Dungeon Crawler
 
Posts: 126
Joined: Thu Jul 18, 2013 8:36 pm
Location: Sawbridgeworth , UK

Re: 7/24/2014 - Creature AI Part 2

PostPosted by Starfia » Fri Jul 25, 2014 5:14 pm

Two days later, I realized I'd read that entire post without noticing the rabbit and the carrot.

EDIT: Wait, it's still well under one day later.
User avatar
Starfia
Bard
Bard
 
Posts: 158
Joined: Thu Jul 18, 2013 5:57 am
Location: Bellingham, Washington

Re: 7/24/2014 - Creature AI Part 2

PostPosted by Gazz » Fri Jul 25, 2014 5:56 pm

I just want to have a wabbit pet and go duck hunting.

DUCK SEASON!
The first rule of Tautology Club is the first rule of Tautology Club. - XKCD
User avatar
Gazz
Henchman
Henchman
 
Posts: 680
Joined: Thu Jul 18, 2013 7:28 am
Location: In your brains. Thinking your thoughts.

Re: 7/24/2014 - Creature AI Part 2

PostPosted by neurobot » Fri Jul 25, 2014 6:52 pm

Is there any way you could allow the player to "turn off" a skill (say, the Stealth skill)? That way, you'd get the full sensory ranges for the to-be-tamed animal—and I kind of like the idea that focusing intently on trying to tame one animal might open you up to attack from other animals, which would be a side-effect of this approach.
User avatar
neurobot
Wanderer
 
Posts: 31
Joined: Thu Jul 18, 2013 5:02 pm
Location: Central Coast, CA, USA

Re: 7/24/2014 - Creature AI Part 2

PostPosted by Vance » Thu Aug 28, 2014 6:05 am

Quite spiffy! I always wanted to tame a wild rabbit and name it after my dog.
Instagram
YouTube
Twitter
User avatar
Vance
Dungeon Crawler
 
Posts: 124
Joined: Thu Jul 18, 2013 5:59 am
Location: United States


Return to Dev Logs

Who is online

Users browsing this forum: No registered users and 1 guest

cron