oolite AI Reference

This page contains reference information regarding the AI system used by oolite. It will be useful for anyone creating an OXP that contains AI elements, or for tinkering with the default AI.

AI Script Format

The AI system consists of a stack of state machines (only the top one of which is active), which respond to game events sent to them as messages. They respond by calling a series of methods which affect the behaviour of the entity and possibly trigger changes to the AI by changing the state or (more drastically) the state machine.

Each state machine (or AI script) is described in a property list in either ASCII or XML format, which can be edited with a text editor or with Property List Editor. The structure is of a dictionary containing each of the machine's possible states referenced by an identifying state name. Each state comprises a dictionary of responses to messages the AI might receive, referenced by the message itself. Each response is an array of methods that will be called when the AI receives that message.

The AI function calls within a message handler are separated from each other by a comma. If a function takes a parameter the value is separated from the function name by a colon and a space, and both the function name and value are enclosed in double quotes.

In ASCII format a simple (two-state) machine looks like this:


{
    "STATE_1" = {
        ENTER = ();
        "MESSAGE_A" = ("method1: value", method2, method3);
        "MESSAGE_B" = (method4, "setStateTo: STATE_2");
        EXIT = ();
        UPDATE = ();
    };
    "STATE_2" = {
        ENTER = ();
        "MESSAGE_A" = ("method1: another_value", method5);
        "MESSAGE_B" = (method6, method7, "setStateTo: STATE_1");
        EXIT = ();
        UPDATE = ();
    };
}

Game defined states and messages

When an AI state machine is started it is always put into the state GLOBAL, and the ENTER message will be sent.

The following table describes each message the game engine may send to an AI state machine.

These messages may be sent while processing commands executed by the AI state machine, or while the AI's controlled entity is performing it's current task.

ACCEPT_DISTRESS_CALL
AEGIS_CLOSE_TO_PLANET
AEGIS_IN_DOCKING_RANGE
AEGIS_LEAVING_DOCKING_RANGE
AEGIS_NONE
APPROACH_COORDINATES
APPROACH_START
APPROACH_STATION
ATTACKED
ATTACKED_BY_CLOAKED

Sent if the ship is attacked by a cloaked ship.

CARGO_SCOOPED
COLLISION
CONDITION_GREEN
CONDITION_YELLOW
COURSE_OK
DEPLOYING_ESCORTS
DESIRED_RANGE_ACHIEVED
DOCKED
DOCKING_ABORTED
DOCKING_COMPLETE
DOCKING_REFUSED
DOCKING_REQUESTED
ECM
ENERGY_FULL
ENERGY_LOW
ENTER

Always sent to the new (now current) state of the AI state machine after switching to a new state.

ENTERED_WITCHSPACE
ESCORTING
EXIT

Always sent to the current state of the AI state machine before switching to a new state.

EXITED_WITCHSPACE

Sent when a ship is added to the system using the addShips: script command, or when it is added to replace a ship that witchespaced out; see also EXITED WITCHSPACE below.

EXITED WITCHSPACE

Sent when a ship is ressurected in a new system after witchspacing out and being followed by the player.

FACING_DESTINATION
FIGHTING
FLEEING
FRUSTRATED
GONE_BEYOND_RANGE
GROUP_ATTACK_TARGET
HOLD_FULL
HOLD_POSITION
INCOMING_MISSILE
LANDED_ON_PLANET
LAUNCHED
MOTHER_LOST
NO_STATION_FOUND
NO_TARGET
NOT_ESCORTING
NOTHING_FOUND
ODDS_BAD
ODDS_GOOD
ODDS_LEVEL
REACHED_SAFETY

Sent when the ship controlled by the AI is fleeing it's primary_target and is at least desired_range kms from it.

RED_ALERT
RESTARTED

Sent when an AI state machine is made the current AI state machine by becoming the top of the AI state machine stack for a particular entity.

STATION_FOUND
TARGET_CLEAN
TARGET_DESTROYED
TARGET_FOUND

Sent when searching for a target and something suitable is found. The found_target can be made the primary target by calling setTargetToFoundTarget in response to this message.

TARGET_FUGITIVE
TARGET_LOST
TARGET_CLOAKED

Sent before TARGET_LOST when the target becomes invisible (starting in Oolite 1.71).

TARGET_MARKED
TARGET_MINOR_OFFENDER
TARGET_OFFENDER
THARGOID_DESTROYED
TRY_AGAIN_LATER
UPDATE

This message is sent to the current state each time the AI gets a chance to "think".

WAIT_FOR_SUN
WAYPOINT_SET
YELLOW_ALERT
CLOSE CONTACT

This message is sent when the ship comes close to another ship, if it is tracking close contacts.

POSITIVE X TRAVERSE

This message is sent when a close contact moves away in the +X direction.

NEGATIVE X TRAVERSE

This message is sent when a close contact moves away in the -X direction.

POSITIVE Y TRAVERSE

This message is sent when a close contact moves away in the +Y direction.

NEGATIVE Y TRAVERSE

This message is sent when a close contact moves away in the -Y direction.

POSITIVE Z TRAVERSE

This message is sent when a close contact moves away in the +Z direction.

NEGATIVE Z TRAVERSE

This message is sent when a close contact moves away in the -Z direction.

RACEPOINTS_SET

Sent by setRacepointsFromTarget on success (used for racing AI).

NAVPOINT_REACHED

Sent when the ship reaches a navigation point (used for racing AI).

ENDPOINT_REACHED

Sent when the ship reaches the last navigation point (used for racing AI).

AI State Machine Function Reference

pauseAI
Parametersdouble intervalThe number of seconds to pause this AI.
This method pauses the calling AI for the number of seconds specified by the interval parameter.
 
setDestinationToCurrentLocation
Parametersnone 
This method sets the destination of the current entity to its current location plus a random offset of up to 0.5 metres in the X, Y, and Z coordinates. This can be used to make a ship idle in a small area of space without being completely still.
 
setDesiredRangeTo
Parametersdouble rangeThe desired range for some operation, in metres.

Some methods (such as scanForNearestMerchantmen, checkCourseToDestination, checkDistanceTravelled, etc) require a "desired range" parameter to be set before they can be used.

This method is used to set the desired range. There is only one value for desired range within an instance of the AI. The value of desired range is modified internally by AI methods such as fightOrFleeMissile, setCourseToWitchpoint, and setPlanetPatrolCoordinates.

 
setSpeedTo
Parametersdouble speedThe desired absolute speed for the current entity.

Sets the speed of the current entity to an absolute value.

If this value is greater than the current entity's maximum speed the entity will travel at maximum speed.

 
setSpeedFactorTo
Parametersdouble speedThe fraction of maximum speed to use.

Sets the speed of the current entity to a fraction of its maximum speed.

For example, to set an entity to move at 35% of its maximum speed, supply a speed parameter of value "0.35".

 
performFlyToRangeFromDestination
Parametersnone 
Condition on exitCONDITION_FLY_RANGE_FROM_DESTINATIONAlways.

Sets the AI's current state to CONDITION_FLY_RANGE_FROM_DESTINATION.

While in this state the entity will attempt to fly to its current destination, stopping at the desired range from it.

 
performIdle
Parametersnone 
Condition on exitCONDITION_IDLEAlways.

Sets the AI's current state to CONDITION_IDLE and resets the frustration factor to zero.

Unlike performHold the current speed is not modified.

 
performHold
Parametersnone 
Condition on exitCONDITION_TRACK_TARGETAlways.

Sets the entity's speed to zero, sets the AI's current state to CONDITION_TRACK_TARGET and resets the frustration factor to zero.

 
setTargetToPrimaryAggressor
Parametersnone 

If there is no current primary agressor against the caller, or the caller has already targeted the primary agressor, this function does nothing.

If there is a primary agressor and the caller is not currently attacking another target, the primary agressor is targeted.

If the caller is already attacking another entity there is a 75% chance it will continue to attack the current target rather than change its target to the primary agressor.

The game decides which entity, if any, is currently the primary agressor against the caller.

 
performAttack
Parametersnone 
Condition on exitCONDITION_ATTACK_TARGETAlways.

Tells the caller to start attacking its current target.

 
scanForNearestMerchantmen
Parametersnone 
MessageTARGET_FOUNDIf a suitable merchant vessel is found within scanner range.
MessageNOTHING_FOUNDIf no suitable vessel is found within scanner range.

Looks for the nearest merchant vessel (including the player's ship) within scanner range.

The calling entity remembers the targeted ship, but it does not become the current target. It can be made the current target by responding to the TARGET_FOUND message with a call to setTargetToFoundTarget.

 
scanForRandomMerchantmen
Parametersnone 
MessageTARGET_FOUNDIf at least one merchant vessel is found within scanner range.
MessageNOTHING_FOUNDIf no merchant vessels are within scanner range.

Randomly selects one of the merchant vessels within scanner range.

The calling entity remembers the targeted ship, but it does not become the current target. It can be made the current target by responding to the TARGET_FOUND message with a call to setTargetToFoundTarget.

The player's ship has an equal chance of being selected, if it is within scanner range. The internal game setting of PIRATES_PREFER_PLAYER is ignored in this function.

 
scanForLoot
Parametersnone 
MessageTARGET_FOUNDIf at least one scoopable item is found within scanner range.
MessageNOTHING_FOUNDIf there are no scoopable items in scanner range, controlling entity does not have a fuel scoop, or controlling entity is a station.

Selects the nearest scoopable item within scanner range.

The calling entity remembers the item, but it does not become the current target. It can be made the current target by responding to the TARGET_FOUND message with a call to setTargetToFoundTarget.

 
scanForRandomLoot
Parametersnone 
MessageTARGET_FOUNDIf at least one scoopable item is found within scanner range.
MessageNOTHING_FOUNDIf there are no scoopable items in scanner range, controlling entity does not have a fuel scoop, or controlling entity is a station.

Selects a random scoopable item from all those within scanner range.

The calling entity remembers the item, but it does not become the current target. It can be made the current target by responding to the TARGET_FOUND message with a call to setTargetToFoundTarget.

 
setTargetToFoundTarget
Parametersnone 

Makes most recently found target the current target.

 
checkForFullHold
Parametersnone 
MessageHOLD_FULLIf the calling ship's cargo hold is full.

Checks the amount of cargo in the calling ship's hold, and if the hold is full sends the HOLD_FULL message.

 
performCollect
Parametersnone 
Property changeconditionCONDITION_COLLECT_TARGET
Property changefrustration0.0

Sets the caller to collect the primary target, assumed to be a scoopable item.

While in the CONDITION_COLLECT_TARGET condition, the TARGET_LOST message will be received if the target is travelling faster than the collecting ship, and the FRUSTRATED message will be sent after 10 seconds, and thereafter every 5 seconds, while the item has not been collected.

 
performIntercept
Parametersnone 
Property changeconditionCONDITION_INTERCEPT_TARGET
Property changefrustration0.0

Sets the caller to intercept the primary target at maximum speed.

While in the CONDITION_INTERCEPT_TARGET condition, the DESIRED_RANGE_ACHIEVED message will be received if the target is within the current desired_range.

 
performFlee
Parametersnone 
Property changeconditionCONDITION_FLEE_TARGET
Property changefrustration0.0

Sets the caller to flee from the primary target at maximum speed.

While in the CONDITION_INTERCEPT_TARGET condition, the REACHED_SAFETY message will be received once the primary target is at least as far away as the current value of desired_range.

If the caller has a cloaking device, it will be activated.

 
requestDockingCoordinates
Parametersnone 
Property changecoordinatesThe coordinates of the nearest station, if any.
MessageNO_STATION_FOUNDIf there are no dockable entities in the current "universe".

Sets the current coordinates to the nearest space station or other dockable entity in the current game area.

There may be no stations, for example in witchspace, in which case the NO_STATION_FOUND message is sent to the current AI state.

 
getWitchspaceEntryCoordinates
Parametersnone 
Property changecoordinatesSet to appropriate coordinates to enter witchspace.

Sets the current coordinates to an appropriate point to make a witchspace jump.

"Appropriate" means either 10kms away from the nearest station, or if no station is found, the distance that can be flown forward in 10 seconds of flying at maximum speed (note that actual speed is not changed).

 
setDestinationFromCoordinates
Parametersnone 
Property changedestinationSet to the current value of coordinates.

Sets the ship's destination to the current value of coordinates.

 
performDocking
Parametersnone 

Not implemented yet - does nothing.

 
performFaceDestination
Parametersnone 
Property changeconditionCONDITION_FACE_DESTINATION
Requests the ship stop and face the location given by destination.

The message FACING_DESTINATION will be sent when this has been achieved.

 
performTumble
Parametersnone 
Property changeconditionCONDITION_TUMBLE
Requests the ship randomly vary it's pitch and roll until taken out of CONDITION_TUMBLE.

Current speed is not affected.

 
fightOrFleeMissile
Parametersnone 
Property changefound_targetIs set to the missile if AI's ship or one of it's group is the target of the missle. The other ships in the group also have their found_target changed to the missle.
Property changeprimary_aggressorIs set to the missile if AI's ship or one of it's group is the target of the missle. The other ships in the group also have their found_target changed to the missle.
Property changedesired_rangeIs set to 10 kms if the ship decides to flee.
MessageFLEEINGIf the missile is targeted at the AI's ship or one of it's group, and the AI's ship does not have an ECM.
If a missile is in flight and is targeting the AI's ship or another ship in it's group, all ships in the group have their found_target and primary_aggressor properties changed to that missle.

The first missle found is dealt with, range and bearing are not taken into account.

If the AI's ship has an ECM it will use it. If not, the AI's ship and any ships in it's group will flee the missle using performFlee with a desired_range of 10 kms. In this case the FLEEING message is sent to the current AI state.

Ship AI

The following table details the conditions an AI controlled ship may be in. An AI controlled ship is only ever in one of these conditions at a time. The condition is changed during calls to functions during message handlers rather than directly by the AI script.

CONDITION_IDLE The ship will centre it's roll and pitch controls. It will continue to travel at it's current speed.
CONDITION_TRACK_TARGET
CONDITION_FLY_TO_TARGET
CONDITION_HANDS_OFF
CONDITION_TUMBLE
CONDITION_ATTACK_TARGET
CONDITION_ATTACK_FLY_TO_TARGET
CONDITION_ATTACK_FLY_FROM_TARGET
CONDITION_RUNNING_DEFENSE
CONDITION_ATTACK_FLY_TO_TARGET_SIX
CONDITION_ATTACK_MINING_TARGET
CONDITION_FLEE_TARGET The ship will flee from it's primary target at maximum speed.
CONDITION_AVOID_COLLISION
CONDITION_TRACK_AS_TURRET
CONDITION_FLY_RANGE_FROM_DESTINATION
CONDITION_FLY_TO_DESTINATION
CONDITION_FLY_FROM_DESTINATION
CONDITION_FACE_DESTINATION
CONDITION_COLLECT_TARGET
CONDITION_INTERCEPT_TARGET
CONDITION_MISSILE_FLY_TO_TARGET
CONDITION_EXPERIMENTAL
CONDITION_FORMATION_FORM_UP
CONDITION_FORMATION_BREAK
CONDITION_ENERGY_BOMB_COUNTDOWN