Artificial Intelligence Module

This page is a discussion of the Artificial Intelligence (AI) module.

The AI module is designed to handle the determination of behaviors of all non-player entities in the game (characters, creatures, vehicles and starships). Starflight III will utilize a finite-state machine architecture for this purpose, one which should be similar to the one used in the original games but intended to be more robust. The basic architecture of the module is similar to other modules within the game that handle basic data types (such as integers and strings, and particularly flags) and dictionaries. This module is required by all other game modules that require the use of non-player entities (in particular the Planetary Exploration, Encounter, and Basic Combat Modules), though there may be some other applications available in other modules. Artificial intelligence is an essential part of the game (of any game, for that matter), in that it directly provides the player with the sense that the lifeforms, vehicles and starships they encounter have plans and strategies of their own, and thus directly challenge the player's mental and physical abilities. All code for the AI module is located in the sf3\_ai.py file.

## Summary Description

When an active entity is created (a vehicle, starship, creature or character), a method will determine if the entity will be under the player's control or not. If the object will be controlled by the game routine, an AI object will be created and added to the overall object, and will be checked by Panda3D's task manager. The AI object consists of a series of variables (flags in particular), with methods added to the task manager which check the state of those variables. Based on the state of those variables, a command will be sent to the entity to perform an action or set of actions. AI objects remain active at all times as long as the entity with which it is associated still exists; they are destroyed along with the entity they control.

## Data Structure of the AI Object

The following list is an indication of the various variables and methods that will be included in an AI object. This list contains suggested methods and variables. AI objects are meant to exist towards the bottom of an object's hierarchy, and denote an entity that is under the computer's direct control. They may be added to vehicle or creature objects (through which starship and character objects also exist). AI objects have no child objects of their own. As there may be multiple controllable entities in the game at any given time, and number of AI objects may be used in the game (though to keep processing times down, it's recommended to keep the actual number of AI controlled entities as low as possible during the game). They are meant to be loaded by the various controlling modules to vehicle or creature objects when those objects are first created. Their data structure is as follows:

* Class: AI
	+ Integer: nCounter (counter, actions taken when it reaches a certain value).
	+ Dictionary: behaviorFlags
		- *Keys: Flag Names. (These will be seeded by the \_init(state)\_ method as appropriate for a creature or vehicle.)*
		- Values: Flags. Either True or False as the case may be.
	+ Method: \_init(state)\_
	+ Method: tick(self, task)
	+ Method: whatToDo()
	+ Method: changeFlag(flagName)

## Procedures and Notes

### Vehicle/Starship AI

Behaviors of AI-controlled craft are set based on flag groupings. The following set of flags are recommended for AI craft; these are based on the notes from the SF1 design doc.

* Flags for specific craft:
	+ bAttacking (craft is attacking its target. Sets true after the craft has fired once. Cleared when communications are entered or when EDL is Friendly, Neutral or Obsequious (see comms posture flags below.))
	+ bStartAttacking (craft will start attacking its target. Randomly true a small % of the time, such that over a period of a minute or so it will be true 20% of the time)
	+ bStopAttacking (craft will stop attacking its target. Randomly true a small % of the time, such that over a period of a minute it will be true 5% of the time)
	+ bGoNow (craft may perform its currently selected behavior. Random boolean with fairly high probability.)
	+ bCanSurrender (craft may surrender; this is set by the racial behaviors)
	+ bNothingHappening (based on an counter. When communications are not occurring a counter is continually incremented. Sets to true after a certain threshhold. Cleared/counter set to zero when they say something or fire a weapon, or at encounter's end. Takes two minutes for the counter to reach the threshhold).
	+ bNonZeroMoveRate (False if the move rate of the ship equals zero, which occurs if the ship becomes debris (i.e. is destroyed) or is designed that way).
	+ bLongRangeToCenter (AI-controlled crafts stay within 10 range increments of the center of the encounter. True if the centerpoint is greater than 20 range increments to the player)
	+ bFiredProjectile (True if the craft has fired a projectile weapon and that weapon is still active)
* Flags for movement:
	+ bApproach (craft is moving to approach its target)
	+ bMoveAway (craft is moving away from its target)
	+ bEvade (craft is evading its target, or its target's fire)
	+ bMoveRandomNow (Randomly true or false, changes state every twenty seconds on average)
* Flags based on the craft's current system status:
	+ bHasProjs (craft has projectile weaponry)
	+ bHasBeams (craft has beam weaponry)
	+ bHasProjTurrets (craft has projectile turrets. Check record)
	+ bHasBeamTurrets (craft has beam turrets. Check record)
	+ bOkayToShoot (craft may fire. For each vessel in the encounter a check is made to the MissAgain() method to see whether it fires. Each craft record includes a fire rate (const (based on loop speed) \* rate = % chance of firing on any given pass). )
	+ bFireNow: (craft will fire weapons at the next opportunity)
	+ bShieldsUp (ship's shields are currently active)
	+ bWeaponsArmed (ship's weapons are armed and ready to fire)
	+ bProjDead (True if the target's projectile weaponry is inoperative)
	+ bBeamDead (True if the target's beam weaponry is inoperative)
	+ bEnginesDead (True if the target's engines are inoperative)
* Flags based on the current communications posture region (for details, see the discussion under the Communications Module.:
	+ bFriendly (alien is friendly towards the target)
	+ bNeutral (alien is neutral towards the target)
	+ bObsequious (alien is obsequious towards the target)
	+ bHostile (alien is hostile towards the target)
	+ bFight (alien is in an attack mode)
	+ bRun (alien wants to run away)
	+ bSurrendered (alien has surrendered to the target)
* Flags based on the target's actions and conditions:
	+ bIncomingProj (True if the target has fired projectile weaponry and that weaponry is still active)
	+ bLongRange (True if the target is greater than 6 cells from the ship)
* Flags based on events that have occurred in the encounter:
	+ bInComm (True if communications with the target are established)
	+ bTerminated (True if communications with the target have been terminated. Cleared at encounter's end.)
	+ bCall (True if the species will call for reinforcements)
	+ bCalled (True if the species has called for reinforcements)
	+ bLessThanThree (True if there are less than three ships currently present in the alien's fleet)
	+ bScan (True if the species will scan the target's fleet)
	+ bScanned (True if the species has conducted a scan of any ship in the target's fleet)

A function call could be made to check for alien craft movement and firing behaviors. Again, these notes are based on code from the SF1 design document. These are listed in code format; a series of if and elif statements are used to check the condition of certain flags, and result in another function call in the event the conditions are fulfilled.

Weapons Fire Check:

* if not bInComm and not bAttacking and bHostile and bStartAttacking and (bHasProjs or bHasProjTurrets):
	+ fireProj()
* elif not bInComm and not bAttacking and bFight and (bHasProjs or bHasProjTurrets):
	+ fireProj()
* elif not bInComm and bAttacking and (bHasProjs or bHasProjTurrets) and bOkayToShoot:
	+ fireProj()
* elif not bInComm and (bHasProjs or bHasProjTurrets) and bFireNow and not bProjDead:
	+ fireProj()
* elif not bInComm and not bAttacking and bHostile and bStartAttacking and not (bHasProjs or bHasProjTurrets) and (bHasBeams or bHasBeamTurrets) and bShortRange:
	+ fireBeams()
* elif not bInComm and not bAttacking and bFight and not (bHasProjs or bHasProjTurrets) and (bHasBeams or bHasBeamTurrets) and bShortRange:
	+ fireBeams()
* elif not bInComm and bAttacking and not bOkayToShoot and bFireBeamNow and bShortRange:
	+ fireBeams()
* elif not bInComm and (bHasBeams or bHasBeamTurrets) and bFireNow and not bBeamDead and not bLongRange:
	+ fireBeams()

Movement Check:

* if not bInComm and not bHostile and not bObsequious and not bFight and bTerminated and bGoNow and bNonZeroMoveRate and not bIncomingProj:
	+ moveAway()
* elif not bInComm and bObsequious and not bCanSurrender and bNonZeroMoveRate:
	+ moveAway()
* elif not bInComm and bNothingHappening and bNonZeroMoveRate:
	+ moveAway()
* elif not bInComm and bAttacking and bStopAttacking and bNonZeroMoveRate:
	+ moveAway()
* elif not bInComm and not bEnginesDead and bRun:
	+ moveAway()
* elif not bInComm and bNonZeroMoveRate and not bObsequious and bLongRange :
	+ approach()
* elif not bInComm and bNonZeroMoveRate and not bObsequious and bShortRange and bHasBeams and not bHasProjs :
	+ approach()
* elif not bInComm and not bLongRange and not bIncomingProj and not bMoveRandomNow and bApproaching and not bEnginesDead:
	+ approach()
* elif not bInComm and and not bLongRange and not bIncomingProj and bMoveRandomNow and not bEnginesDead:
	+ approach()
* elif not bInComm and bLongRange and bIncomingProj and not bEnginesDead:
	+ evade()
* elif not bInComm and bIncomingProj and not bEnginesDead:
	+ evade()
* elif not bInComm and bNonZeroMoveRate and not bApproach and not bMoveAway and bGoNow:
	+ moveRandom()
* else:
	+ doNothing()

Action Check:

* if not bShieldsUp and not bFriendly and not bSurrendered:
	+ toggleShields() (to raise shields)
* if bShieldsUp and bFriendly:
	+ toggleShields() (to lower shields)
* elif bShieldsUp and bSurrendered:
	+ toggleShields() (to lower shields)
* if not bWeaponsArmed and not bFriendly and not bNeutral and not bSurrendered:
	+ toggleWeapons() (to arm weapons)
* if bWeaponsArmed and not bHostile and not bObseqious and not bFight:
	+ toggleWeapons() (to disarm weapons)
* elif bWeaponsArmed and bSurrendered:
	+ toggleWeapons() (to disarm weapons)
* if bCall and not bCalled and bLessThanThree and not bFriendly and not bNeutral and not bSurrendered:
	+ callBackup()
* if bCalled and bArrive:
	+ addMoreShips()
* if bScan and not bScanned:
	+ scanShip()

#### AI Targeting

AI controlled ships in AI controlled fleets select targets based on three criteria (listed in order of importance)- Relations, Security, and Proximity.

* Relations is how one fleet views another- friendly, neutral or enemy, based on how its owner race views the owner race of the other fleet. A fleet always picks targets from the fleet(s) that have the poorest relations with it. So a ship within an AI controlled fleet will only target members of enemy fleet(s) if there is one or more enemy fleet(s) in the encounter. A ship within an AI controlled fleet will only target members of a neutral fleet if there is one or more neutral fleet(s) but not a single enemy fleet. If there are only friendly fleet(s) in the encounter, then their ships will be targeted. If a ship from a neutral or friendly fleet attacks an AI controlled fleet, it and all other members of its fleet will be considered enemies.
* Security is how much damage has been dealt to an AI controlled ship, by other ships. The ship that has done the most damage in recent history has the lowest security level and is the one that is targeted, unless there are other ships within other fleets that are on a lower relations level (Relations can override Security.)
* Distance is how far away other ships are from the AI controlled ship. The ship that is closest is the one that is targeted, unless there are other ships within other fleets that are on a lower relations level, or are on a lower security level. (Relations and Security can override Distance.)

AI controlled ships in the Player controlled fleet select targets based on what orders the Player has given them- Fly in Formation, Search and Destroy, or Attack the Player's Target.

* While in Formation, Player escorts will select targets solely on Relations and Distance (since they must maneuver to stay close to the player and thus cannot chase ships with low Security levels when they get out of weapons range.)
* While in Search and Destroy mode, Player escorts will select targets using the same thought process as escorts within an AI controlled fleet.
* When ordered to Attack the Player's target, the escort will target it and open fire on it with all weapons capable of hitting it (regardless of normal selection criteria) until given new orders or the target is destroyed (at which point a new target will be selected using the normal selection routine).

#### AI Flight Tactics

There are six categories of flight tactics that AI controlled ships will use during different situations- Formation, Neutral, Flee, Skirmish, Melee, and Intercept.

* Formation means all escorts will try to stay within both missile and laser range of their fleet leader (the flagship in the player-controlled fleet, or a randomly selected ship in an AI-controlled fleet (if the leader is destroyed in an AI controlled fleet, a new one is selected at random. Preference will be given to warships over scouts, over transports when assigning a fleet leader in an AI fleet.))
* Neutral means the ship will simply fly around in random directions.
* Flee means the ship will simply move away from the closest ship within any enemy fleet, as fast as possible.
* Skirmish means the ship will try and maneuver around its target while staying within missile range, but outside of laser range.
* Melee means the ship will try and maneuver around its target while staying within both the missile and laser maximum ranges.
* Intercept means the ship will simply fly directly towards its target, as fast as possible. Once it has overflown its target, it will loop around and repeat its charge.

Regardless of the tactic used, an AI-controlled vessel will fire on a target in an enemy fleet with whatever weaponry it has in range and in the correct arc.

*I'm not entirely sure how best to implement these tactics into gameplay, but I would like to include them if at all possible. Likely the design included herein will need additional work to give us the ability to implement flight tactics. It's also possible this section is already redundant and may be ignored entirely anyway.*

### Creature/Character AI

Behaviors of AI-controlled creatures and sapients are set based on flag groupings. The following set of flags are recommended for AI creatures; these are based on the notes from the SF1 design doc. Note that in addition to treating the player's vehicle as a potential target, non-sapient creatures also have a secondary target (identified herein as a "mate"), another creature with whom that creature will interact.

* Flags for specific creature qualities:
	+ alienSmartEnough: True if intelligence >= 70
	+ dumbEnough: True if its intelligence < 35.
	+ ultraAggressive: True if alien's aggression is >= 80
	+ aggressiveEnough: Is its aggression level >= 40 ?
	+ dangerous: True if Aggression > 65
	+ wussy: True if Aggression < 35
	+ randomScared: 10% chance this will be true.
	+ alienHitWithLaser: True if that alien was just hit.
	+ alienHitWithStunner: True if alien was just hit.
	+ randomPissed: 10% chance this will be true.
	+ canBreakAway: There is a 10% chance this is true.

* Flags for movement:
	+ mobile: Alien's movement rate > 0
	+ moving: is it moving?
	+ onGround: Is its on-ground flag set to True?
	+ canFly: Does it have movement mode of Fly?
	+ canFloat: Does it have movement mode of Float?
	+ canSwim: Does it have movement mode of Swim?
	+ wantsToFly: Some randomly determined chance with a fairly high %
	+ wantsToFloat: Some randomly determined chance with a fairly high %
	+ wantsToSwim: Some randomly determined chance with a fairly high %
	+ wantsToLand: Some randomly determined chance with a low to moderate %.
	+ wandering: Is its behavior set to Wandering?
	+ safeToLand: False if the square the alien is on is liquid, lava, or occupied by another alien or the player.

* Flags based on the creature's location:
	+ alienCloseEnough: True if alien is within 5 squares of the player
	+ nextToPlayer: True if alien is in adjacent square to the player.
	+ nextToMate: Is it in a square adjacent to its mate?
	+ outOfBounds: Is alien outside encounter area?

* Flags based on the creature's current status:
	+ alive: Check status flag.
	+ stunned: Check status flag.
	+ beenEaten: Is the eaten flag set for that alien?
	+ HitsAboveZero: Are the aliens Hits (HP) > 0
	+ StunsAboveZero: Are the aliens Stuns (NHP) > 0
	+ StunsLessThanMaxNHP: Are the Stuns for that instance of an alien < the Stun-points it started with (in species record, i.e. is the creature's NHP ≤ 0).

* Flags based on the creature's niche/mate's niche (a creature will always use the highest niche available to it):
	+ herbivore: creature is an herbivore
	+ producer: creature is a producer (*in SFRPG parlance, creature is photo-synthetic or chemo-synthetic*)
	+ carnivore: creature is a carnivore
	+ omnivore: creature is an omnivore
	+ mateHerbivore: creature's mate is an herbivore
	+ mateProducer: creature's mate is a producer
	+ mateCarnivore: creature's mate is a carnivore
	+ mateOmnivore: creature's mate is an omnivore

* Flags based on the mate/target's actions and conditions:
	+ playerFiringLaser: True when player fires. Set back to false shortly afterwards.
	+ mateAlive: Check status flag of mate.
	+ mateApproaching: Is its mates behavior flag set to Approaching?
	+ mateAttacking: Is its mate's behavior flag set to Attacking?
	+ mateOutOfBounds: True if an aliens mate is outside the encounter area.
	+ mateJustEaten: A flag is set or something - hell I dont know.
	+ mateOnGround: Is on-ground flag set for the mate?
	+ hasMate: Is it paired up with a mate?
	+ bigEnough: Is the alien's size (1-9) >= its mate's size - 2 ?

* Flags based on events:
	+ noticePlayer: Queries a flag to see if alien has become aware of player. If it is false a determination is made with a small random chance that it will become true.
	+ mateAttacked: Set to true once an alien has attacked its mate. Set to false if an alien is not next to its mate.
	+ randomlyUnpaired: A random determination such that this will happen every now and then.

A function call could be made to check for creature movement and attack behaviors. Again, these notes are based on code from the SF1 design document. These are listed in code format; a series of if and elif statements are used to check the condition of certain flags, and result in another function call in the event the conditions are fulfilled.

Lifeform Behavior Procedure:

1. Pair all unpaired lifeforms in the encounter area (18x by 30y cells - twice the visible area)
2. For each lifeform in the encounter area:
	1. Do behavior with Expert System Behavior Controller
	2. Do a lifeform status check
	3. Do Terrain Transitions
	4. Repeat until all lifeforms have been accounted for.
3. Repeat as necessary.

Expert System Behavior Controller Procedure/Pseudocode:

* #(Make aliens scared or angry with laser)
* if playerFiringLaser and alienCloseEnough and alienSmartEnough and not ultraAggressive and randomScared:
	+ reduceAggression()
* elif (alienHitWithLaser or alienHitWithStunner) and dumbEnough and randomPissed and not producer:
	+ increaseAggression()
* #(Do any action and go to the next level)
* #(Response to Player)
* actionlevel=0
* if mobile and alive and not stunned and noticePlayer and dangerous and not nextToPlayer:
	+ approachPlayer()
	+ actionlevel=1
* elif alive and not stunned and noticePlayer and dangerous and nextToPlayer:
	+ attackPlayer()
	+ actionlevel=1
* elif mobile and noticePlayer and alive and not stunned and wussy:
	+ evade()
	+ actionlevel=1
* #(if any action is done jump to Lifeform Status Check, else drop to next level.)
* if actionlevel != 0:
	+ statusCheck()
* else:
	+ #(Response to Other Lifeform)
	+ if mobile and alive and not stunned and (herbivore or omnivore) and mateProducer and not nextToMate and mateOnGround and hasMate:
		- approachMate()
		- actionCheck = 1
	+ elif mobile and alive and not stunned and (carnivore or omnivore) and mateHerbivore and bigEnough and not nextToMate and mateOnGround and hasMate:
		- approachMate()
		- actionCheck = 1
	+ elif mobile and alive and not stunned and not herbivore and not producer and not mateHerbivore and not mateProducer and bigEnough and ultraAggressive and not nextToMate and mateOnGround and hasMate:
		- approachMate()
		- actionCheck = 1
	+ elif mobile and alive and not stunned and mateApproaching and hasMate:
		- evadeMate()
		- actionCheck = 1
	+ elif mobile and alive and not stunner and mateAttacking and aggressiveEnough and canBreakAway and hasMate:
		- evadeMate()
		- actionCheck = 1
	+ elif alive and not stunned and (herbivore or ominvore) and mateProducer and nextToMate and mateAlive and hasMate:
		- attackMate()
		- actionCheck = 1
	+ elif alive and not stunned and (carnivore or omnivore) and mateHerbivore and bigEnough and nextToMate and mateAlive and hasMate:
		- attackMate()
		- actionCheck = 1
	+ elif alive and not stunned and not herbivore and not producer and not mateHerbivore and notMateProducer and bigEnough and ultraAggressive and nextToMate and mateAlive and hasMate:
		- attackMate()
		- actionCheck = 1
	+ elif alive and not stunned and mateAttacking and aggressiveEnough and hasMate:
		- attackMate()
		- actionCheck = 1
	+ elif alive and not stunned and not carnivore and not producer and not mateProducer and mateAttacked and not mateAttacking and nextToMate and hasMate:
		- eatMate()
		- actionCheck = 1
	+ elif alive and not stunned and not carnivore and not producer and mateProducer and not mateAlive and nextToMate and hasMate:
		- eatMate()
		- actionCheck = 1
	+ elif alive and not stunned and not producer and not herbivore and not mateProducer and not mateAlive and nextToMate and hasMate:
		- eatMate()
		- actionCheck = 1
	+ elif hasMate and (mateOutOfBounds or randomlyUnpaired or mateJustEaten):
		- becomeUnpaired()
		- actionCheck = 1
		1. (if any action is done jump to Lifeform Status Check else go to next level)
	+ if actionCheck != 0:
		- statusCheck()
		1. (Default behavior for mobile aliens)
	+ elif alive and not stunned and mobile:
		- wanderAround()
	+ else:
		- doNothing()

Lifeform-Status Check Procedure/Psuedocode:

* def statusCheck()
	+ if outofBounds or beenEaten:
		- eraseLifeformFromArray()
	+ if HitsAboveZero and alienHitWithLaser:
		- reduceHitsByTenToFifty()
	+ elif mateAttacking and HitsAboveZero:
		- reduceHitsByOneToForty()
	+ elif StunsAboveZero and alienHitWithStunner:
		- reduceStunsByTenToFifty()
	+ if not StunsAboveZero:
		- stunEffectsHits()
	+ if not HitsAboveZero and alive:
		- die()
	+ elif not StunsAboveZero and not stunned:
		- stunned()
	+ elif StunsAboveZero and stunned:
		- unstunned()
	+ if alive and stunned and StunsLessThanMaxNHP:
		- incrementStuns()

Terrain Transition Procedure/Pseudocode:

* if moving and onGround and canFly and wantsToFly:
	+ fly()
* elif moving and onGround and canFloat and (producer or (not producer and wantsToFloat)):
	+ float()
* elif moving and onGround and canSwim and (producer or (not producer and wantsToSwim)):
	+ swim()
* elif alive and not onGround and safeToLand:
	+ land()
* elif stunned and not onGround and safeToLand:
	+ land()
* elif not onGround and wandering an wantsToLand and safeToLand:
	+ land()
* elif not onGound and (status==attacking) and safeToLand:
	+ land()

General effects of indicated Creature-Related Methods:

* reduceAggression() - Subtract a random no. from 1 to 50 from the aggression level of alien.
* increaseAggression() - Add a random no. from 1 to 20 to aggression level of alien.
* approachPlayer() - Move alien towards the player (see movement conditions). Sets moving flag to Yes.
* attackPlayer() - Determine whether or not alien hits or misses. Distribute any damage, and print out result-phrase. Sets Moving flag to No.
* evade(): Move alien away from target. Sets Moving flag to Yes.
* approachMate: Move alien towards its mate (see movement conditions). Sets Moving flag to Yes, and Behavior flag to Approaching.
* evadeMate(): Move alien away from its mate (see movement conditions). Sets Moving flag to Yes, and Behavior flag to Fleeing.
* attackMate(): Sets moving flag to No, and Attacking flag to Yes.
* eatMate(): Roll a RND no. from 1 - 100. If it is less than 10 then the mate is eaten and it disappears. Some flag is set to indicate the alien has been eaten.
* becomeUnpaired(): Un-link lifeform from it's mate.
* wanderAround(): Move alien in Random direction. Base direction on species address value so aliens will move in straight lines. Then add some random variation to this. (see movement conditions)
* fly(): Sets current movement mode to flying.
* float(): Sets current movement mode to floating.
* swim(): Sects current movement mode to swimming.
* land(): Sets current movement mode to ground.
* doNothing(): Default state, lifeform performs no actions.

*These methods are also indicated. However, their function appears to be redundant with functions included in the Combatant object; they'd be redundant if left within the AI object. For details on the methods of combatant objects, see the discussion under the Basic Combat Module.*

* eraseLifeformFromArray(): This is the list of all aliens being operated on in the encounter area.
* reduceHitsByTenToFifty(): Roll a RND no. from 10 - 50 and subtract from the alien's Hits.
* reduceHitsByOneToForty(): Roll a RND no. from 1 - 40 and subtract from the alien's Hits.
* reduceStunsByTenToFifty(): Roll a RND no. from 10 - 50 and subtract from the alien's Stuns.
* stunEffectsHits(): Take the absolute value of the Stuns and subtract it from the Hits. Then set Stuns to 0. *Bleed-over damage, looks like.*
* die(): Set alien's status to DEAD.
* stunned(): Set alien's status to STUNNED.
* unstunned(): Set alien's status to NOT STUNNED.
* incrementStuns(): add one to the Stuns of that alien.

#### Creature Attack Formula

When a lifeform attacks the terrain vehicle, it either has a 80% chance of hitting or a 20% chance of hitting (if the flat device/TV shield is used). Lifeforms must be near the terrain vehicle in order to attack crew. Crewmember attacked is picked at random, as per the formula below.

* Determine number of attacks:
	+ Roll RND no. from 1 - 100.
		- 1-70 = 1 attack
		- 71-95 = 2 attacks
		- 96-100 = 3 attacks
* For each attack choose a crew member at random.
	+ Determine success of attack:
		- Roll a RND no. from 1 - 100
		- If value is < avg. of alien's aggression and
		- intelligence then attack is successful.
	+ Determine damage (from creature record):
	+ Result Phrase:
		- " The identifier lifeform attacks (crew name)"
		- if it misses:" and misses."
		- if it hits  :". (Crew name) is status." (status is same as in Doctor)

Sentient lifeforms will attack the terrain vehicle if the terrain vehicle has fired on sentients on foot or in a vehicle within the last five days, and/or if they are a spacefaring race and the player is on hostile terms with them in space, or if they are simply a hostile race to begin with. Sentient lifeforms attack with ranged weapons that can fire on the player anywhere on the zoomed in map viewpoint. The damage rating and description of their attacks depend on their technology level (Stone Age, Metal Age, Industrial Age, Starfaring Age).

#### Creature Movement Conditions

* Creatures move by an increment that is determined by their movement rates. If their movement mode is ground every time they move a check is made to see if the square they are moving onto is a) liquid (if the creature either cannot or does not want to swim), b) lava, or c) already occupied. If any of these are the case a different target square is chosen. Creatures in the air or swimming creatures do not need to make any of these checks.

## Methods

(use this area to list the module's methods and give a description of what the method does. As the methods are written, what they do should be written out procedurally)

### \_init\_(state)

This method's purpose is to load up the set of behaviors necessary for a computer-controlled object. The argument passed to the method determines the specific set needed (whether for a vehicle/starship or creature/character).

### tick(self, task)

This method's purpose is simply to move the AI object's nCounter, passing itself to the Panda3d task manager. All it does when called is increment nCounter by one, and then check nCounter's value to see if an action may be performed. The method returns task.cont, allowing for continuous monitoring in the task manager.

### whatToDo()

This method's purpose is to check the value of the flags and initiate an appropriate course of action based upon those flags. This one will ultimately require more methods, one for each possible behavior. *For the procedures listed in the notes above, this is the controlling method; it will first check to see if it's dealing with a vehicle or a creature, then activate the appropriate procedure from there.*

### changeFlag(flagName)

This method's purpose is to change the value of a flag. It simply finds the indicated flag passed to it as an argument and flips its value from True or False or vice versa.

## Module Status

*This is current as of August 3, 2011.*

This module is currently in the final design phases; while specific descriptions of the intended functions of modules have yet to be written, the remainder of the module's basic description is complete at this point. Further design work on this module has been frozen for the time being, and will remain so until I'm ready to begin method descriptions for all remaining extant modules. I feel this module is more complete than other recent modules, and while it will need additional methods to work the way its intended to, I don't think those methods will be overly complicated. I'm fairly certain that the procedures already here should cover the AI needed for the game. What's here should be more than sufficient for the design team to proceed with coding of the module.

NEXT: Starport

PREVIOUS: Basic Combat Module

TOP