-
Notifications
You must be signed in to change notification settings - Fork 11
AI Decision Making
###Overview Every time a player submits a move request while AI are present in a room, each of the AI gets a chance to compute a move. One of the final stages of each player move request processor (Move, Hack, Drain, ...) is to run the AIMoveRequestProcessor. In broad strokes, the AIMoveRequestProcessor does the following:
- Gather up a list of all entities (players, energy tanks, other AI) in the room that the player move was made in
- Get the (hopefully) cached room nav mesh/visibility
- Compute the path for the player that moved
- Compute the move for each AI
###Mob Update Context The MobUpdateContext is a temporary collection of all of the state a single AI needs to make its next move. During the Update call, the mob updates its perception state about the world and the evaluates its behavior tree. The update context also has helper methods for performing specific AI actions (drain, hack, move, ...) The output the update context is a set of game events that correspond to actions that the AI took as part of their move.
###Mob Perception Seeming realistic AI shouldn't have omniscient knowledge of the player. This is especially true in a game with any kind of stealth component to it. AI should have some kind of perception model that constrains how they gain information about their environment and how they distribute that knowledge to other AIs. In this game each AI has a vision cone that defines an angle and range restriction about what the AI can see. At some point I'll probably have a basic "hearing" model as well (based off of dialog events other AI post).
AI store their knowledge about other entities (players, energy tanks, other AI) in what we call a Prop. A prop contains the most recent set of info the AI has about another entity that they have (or had) perception of. For example, if an AI can directly see a player, the prop would be located directly on the player and would have up to date info about the players state. Once the player moves into cover, the prop gets moved to the last place the AI saw the player, and the prop information becomes stale.
Props have the following properties they gather from entities:
- target_entity_id - The object id of the entity the prop is associated with
- position - The last known location of the entity (the current location if the entity can be seen)
- faction - Friend, Enemy, or Neutral
- energy - The amount of energy the entity has remaining
Props also have the following derived properties:
- distance - The current distance to the prop location
- propStatus
- Unacknowledged - AI doesn't even know this object exists yet
- Orphaned - AI saw (or heard) this entity at some point but it ran away from them
- Assumed - AI saw (or heard) this entity the AI moved away from it
- Acknowledged - AI can see this entity
- propStatusTurnCount - How many turns has the status stayed the same
- salience - A normalized score denoting how important the prop is to the AI
- visibilityFlags - Flags denoting how we see or have seen the prop
Prop state is updated as follows:
- Delete any props for entities that have been deleted
- Create props for entities that have come into existance
- Compute the visibility flags and last visible position for each prop
- This takes into account the players path, so even if the player is hidden at the end of their move, if the players path cross the AI's vision cone we update the prop to the last visible location
- Update the prop status enum based on the updated vision state
- Compute a salience score for each prop i.e. how important is this prop?
- Pick a target enemy, friendly, and neutral prop based on the best salience scores
- The target enemy is the player that we want to engage
- The target friend is an AI that we want to help most
- The target neutral is an energy tank that we want to hack or drain
After the perception update is complete we serialize the perception state into a JSON blob that gets written back into the DB. We do this so that we don't forget about our props after each turn.
###Mob Behavior Selection Once an AI has an updated state of the world they can make a decision about what they want to do this turn. All of the decision making logic is arranged into a Behavior Tree, which is a tree of individual Behavior classes. Each Behavior class has a CanActivate method that decides if the behavior currently wants to run and a Perform method that emits actions for the AI if the behavior wants to run. Each behavior also have a list of child behaviors that we will recursively call CanActivate on if the parent behavior decides to activate. We stop looking for behaviors to activate if one of our child behaviors activated. Therefore child behaviors earlier in the child list have priority. There is only one behavior tree in the game, but each AI can only activate a subset of the behaviors. The current behavior tree is arranged as follows:
- Root
- SelfPreserve
- TakeEnergyFromTank - [Stub] Run to an energy tank that we knew about but cant see if our health is low
- RequestRepair - [Stub] Post a call for health from a friend
- RequestEnergy - [Stub] Post a call for energy from a friend
- Flee - [Stub] Hide from our enemy target
- Combat
- RepairFriend - [Stub] Give health to a friend who requested it
- GiveEnergyToFriend - [Stub] Give energy to a friend who requested it
- AttackEnemy - [Stub] Do damage to an enemy we can se
- SpawnHelperBot - [Stub] Spawn a helper bot
- Search
- InvestigateEnemyStimuli - Move to an orphaned enemy prop
- InvestigateFriendlyStimuli - [Stub] Move to a friend who made a call for help
- Patrol
- DrainEnergyTankBehavior - Pull energy from a tank that we can see that belongs to the AI team
- HackEnergyTank - Convert an enemy energy tank to a friendly energy tank
- AimlessWander - Randomly pick a point nearby to wander to
- SelfPreserve
Server Project Organization - How the files in the server project are arranged
Mob Types - Format for the mob type definitions
Room Templates - How the room templates are validated and stored in the DB
Navigation - How AI navigation is computed on the server
AI Decision Making - How AIs make decisions in response to players moves
Request Processors - How incoming JSON requests are processed
Database Query Layer - How database queries are structured and cached
Standalone And Embedded Web Server - How the stand alone and client embedded web server are structured
ASPX Web Service - How the IIS hosted web server is structured
Client Project Organization - How the files in the client project are arranged
UI System - Wrapper around Unity immediate mode UI and UI event handling
Asynchronous Request System - How JSON requests are sent to the web server
Game Event System - How the game state changes as a result of player actions
AI Path Finding and Steering - How the AI compute a path and drive toward path waypoints
IRC and Push Notifications - How chat and server push notifications are routed through IRC