OXP howto AI

From Elite Wiki
Revision as of 11:59, 1 August 2008 by Eric Walch (talk | contribs) (Communication)

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 = ();
     };
}

The same script in XML.


AI

Messages to the statemachine with a priority are displayed in boldface.

Method Description
exitAI Exits current AI and returns to the same state in the old AI that called this AI with a "setAITo:". It returns: "RESTARTED".
pauseAI:(NSString *)intervalString Sets next AI update time in seconds. It does not stop the execution of the remainder of the line. It just sets the next UPDATE time to the current time plus the pause time. The pauseAI commands are non-cumulative.
setAITo:(NSString *)aiString Pauses current AI and switches to anotherAI.plist, this becomes the top AI on the 'AI-stack'.

When anotherAI.plist exits (exitAI), the previousAI becomes topAI again and AI-state is messaged "RESTARTED".

setStateTo: SOMESTATE Changes the AI state to SOMESTATE.
switchAITo:(NSString *)aiString Switches entity AI to another *AI.plist, the previous AI will be exited.

AI choices

Method Description
fightOrFleeHostiles Deploys escorts if he has them. If he has enough missiles left he might fire one. Then decides between issue the FIGHTING or FLEEING message. Returns "FIGHTING", "DEPLOYING_ESCORTS" or "FLEEING".
fightOrFleeMissile Deals with missiles, uses ECM if available, flees if not, marks as offender if police. Returns: "FLEEING" or nothing.

Perform Action

Method Description
becomeEnergyBlast Used in the Q bomb.
becomeExplosion The entity model is replaced by an explosion. If player is docked at exploding station it first launches the player.
becomeLargeExplosion Used at player entity death, not for use in other instances.
dealEnergyDamageWithinDesiredRange Needs desiredRange to be set first, then deals weaponEnergy (Shipdata.plist) damage within this sphere.
decreaseAlertLevel Can only be used on stations. Decreases station alertlevel. Returns: "CONDITION_YELLOW", "CONDITION_GREEN".
deployEscorts Sends the mothers primary target to all escorts and sets the statemachine of all the escorts to: interceptAI.plist.
dockEscorts Gives all existing escorts a dockingAI.plist and sets the state to ABORT so the escorts go to a waiting position for docking.
ejectCargo Ejects cargo.
enterTargetWormhole Will locate nearest wormhole, and enter it.
escortCheckMother Returns "ESCORTING" or "NOT_ESCORTING".
fireECM Used by stations and hermits to engage ECM.
fireMissile Fires missiles on selected target. It sends a "INCOMING_MISSILE" message to the target state machine.
groupAttackTarget All ships in group will have their targets set to this entity's current target. It will return "GROUP_ATTACK_TARGET" to the sending ship as well as to all group members.
increaseAlertLevel Can only be used on stations. Increases station alertlevel. Returns: "YELLOW_ALERT", "RED_ALERT".
landOnPlanet Selects the nearest planet it can find, increments the landed shuttles counter for that planet and 'removes' the entity. Returns: "LANDED_ON_PLANET"
Launch..SomeShip Launches a ship fron a dockable entity, various types of this method exist. See also Station Ships.
  • LaunchDefenseShip
  • LaunchEscort
  • LaunchMiner
  • LaunchPatrol
  • LaunchPirateShip
  • LaunchPolice
  • LaunchScavenger
  • LaunchShipWithRole: <Role>
  • LaunchShuttle
  • LaunchTrader
markTargetForFines Deals out a fine to target. It returns: "TARGET_MARKED". When the target was no ship it returns: "TARGET_LOST".

Example:

"markTargetForFines: 100"

Will fine the target 10Cr. N.B. for commercial transactions "awardMoney -$" is a more suitable method.

markTargetForOffence:(NSString*) valueString Has police mark up the criminal record (Legal status) of target entity. The value is not added to the criminal record but a bit-wise OR is used between value and criminal record. It returns: "TARGET_LOST" when the target was no ship.
messageMother:(NSString *)msgString Sends a AI priority message to the mothership/leader of a group.

Example:

INCOMING_MISSILE = ("messageMother: INCOMING_MISSILE");

The mothership will then behave as if it was targeted by the missile. But you don't have to use standard message names, you can also send self defined message names were the mother can react on.

performAttack Attacks target.
performCollect Performs 'collection' of target.
performDocking NOT YET IMPLEMENTED.
performEscort Performs escorting. Needs a desired range first. The escorts follow at the desired range. See also Escort Instructions.
performFaceDestination Has entity face destination. Returns "FACING_DESTINATION" when turn is completed.
performFlee Sets the caller (AI) to flee from it's primary target at maximum speed. If the caller has a cloaking device, it will be activated. It needs a range to be set first. When the ship outruns the attacker by this distance it returns: "REACHED_SAFETY".
performFlyToRangeFromDestination With this command the ship can react in two ways. It first looks at the distance to the target. When it is closer to the target than the previously defined desired range, it will fly away from the target, otherwise it will fly toward the target. It stops the ship at the desired range from the destination and than returns: "DESIRED_RANGE_ACHIEVED".
performHold Performs idleness while tracking a potential target, speed is set to zero. frustration level is reset.
performHyperSpaceExit Gets a list of destinations within fuel range, checks if clear of nearby masses, and select one at random. May return "WITCHSPACE UNAVAILABLE", "WITCHSPACE BLOCKED" or "WITCHSPACE_OKAY". It will add a new ship with the same role as the leaving ship at the witchspace entry point.

When the player performs a hyperspace exit or a galactic jump, all NPC ships get the priority message: "PLAYER WITCHSPACE".

performHyperSpaceExitWithoutReplacing Gets a list of destinations within fuel range, checks if clear of nearby masses, and select one at random. May return "WITCHSPACE UNAVAILABLE", "WITCHSPACE BLOCKED" or "WITCHSPACE_OKAY". This command will not add a new ship at the witchspace entry point. (available with version 1.70 and higher)
performIdle Performs idleness. Ship corrects its roll and pitch to 'horizontal' flight, speed is unaffected. frustration level is reset to zero.
performIntercept Performs target interception. It needs a range to be set first. When the distance to target becomes less than desired range it returns: "DESIRED_RANGE_ACHIEVED". When target lost: "TARGET_LOST". When it hasn't come closer to target for 10 seconds it returns: "FRUSTRATED"
performMining Performs mining. (Finds, intercepts and shoots asteroids with mining laser, if fitted.) It returns: "TARGET_LOST".
performTumble Performs random pitch and roll, 'evasive maneuvers'.
setSpeedTo:(NSString *)speedString Sets desired speed to an absolute value, entity cannot go faster than maxspeed value determined in the shipdata.plist. If speed is above maxspeed, entity will use fuel injectors if available.
setSpeedFactorTo:(NSString *)speedString Sets the desired speed to a percentage of maxspeed (0->1=0%->100%). If speedfactor is set above 100%, entity will use fuelinjectors if available.
setUpEscorts Useful to quickly establish (by name and number the shipdata.plist prescribed) escorts, when a ship is introduced to a system. See also Escort Instructions.
suggestEscort Has an escort seek employment and either gets accepted or rejected by the "mother". See also Escort Instructions.
switchLightsOff If an entity has lights (or flashers), this command will turn them off. Default state is on. (See shipdata.plist)
switchLightsOn Will turn flashers back on.
wormholeEntireGroup Wormholes ships in this group. Returns "ENTER WORMHOLE"
wormholeEscorts Wormholes official escorts. Returns "ENTER WORMHOLE"
wormholeGroup Wormholes ships in group of which this is a leader. Returns "ENTER WORMHOLE"

Navigation

Method Description
**** The aegis check is part of the system update and messages needs no command to generate them. The following messages are only generated when the status changes.

"AEGIS_CLOSE_TO_PLANET": Within 3x planetary radius and not near station. "AEGIS_IN_DOCKING_RANGE": Within 2x scanner radius of system station. "AEGIS_LEAVING_DOCKING_RANGE": Has been in docking range but now only close to planet. "AEGIS_NONE": None of the above three messages is true.

**** The surface check needs no command. It automatically generates messages when a ship passes a border at approximately 1 meter from the main planet surface.

"APPROACHING_SURFACE": passed the border inward. "LEAVING_SURFACE": passed the border outward.

abortDocking Signal the mother station that the docking is aborted. see Docking Instructions
getWitchspaceEntryCoordinates Calculates coordinates at 10 km from the rotation axis of the nearest station it can find, or just fly 10s forward.
recallDockingInstructions see Docking Instructions
requestDockingCoordinates Requests coordinates from the nearest station it can find (which may be a Rock hermit). Returns: "NO_STATION_FOUND", "TRY_AGAIN_LATER", "HOLD_POSITION", "BACK_OFF" , "APPROACH" or "APPROACH_COORDINATES". see also Docking Instructions
setCoordinates:(NSString *)system_x_y_z Sets destination coords, see addShipsAt. It needs 4 parameters separated with space. When coordinates are set it returns: "APPROACH_COORDINATES". You can even randomize positive coordinates.
setCourseToPlanet Selects the nearest planet it can find, sets the coordinates to a point on the ship's side of the surface with a large random spread to avoid all ships flying to the same point. Then it sets the desired range to 50 m (+ its own collision diameter). This short desired range will probably crash normal fast flying ships on the surface but a collision between the planet and a ship with role "shuttle" is interpreted as landing.
setCourseToWitchpoint Sets destination coords to Witchpoint area and sets "DesiredRange" to 10 km.
setDesiredRangeTo:(NSString *)rangeString 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.

setDestinationFromCoordinates Enables the plotting of manual waypoints.
setDestinationToCurrentLocation 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.
setDestinationToDockingAbort DockingAbort coordinates 8000 meter distance from the docking slit.
setDestinationToStationBeacon Sets destination at 10 km ahead of the docking slid (of the main station). The station beacon itself needs not to be present.
setDestinationToTarget Sets destination to target coords.
setDestinationToWitchpoint Sets destination coordinates to WitchspaceExitPosition.
setDestinationWithinTarget Handy for ramming and racing.
setPlanetPatrolCoordinates Request coordinates for planet control. Read more in setPlanetPatrolCoordinates.
setSunSkimEndCoordinates ...
setSunSkimExitCoordinates ...
setSunSkimStartCoordinates ...
setTargetToSystemStation ...
setTargetToStation ...
setTakeOffFromPlanet Selects the nearest planet it can find and calculates a vector perpendicular to the surface and sets a destination range of 10 km. Does nothing if there is no planet to be found.

Communication

Method Description
****** Hitting a clean ship automatical sends a "OFFENCE_COMMITTED" to all nearby ships with scanClass equal CLASS_NEUTRAL, CLASS_STATION, CLASS_BUOY, CLASS_POLICE, CLASS_MILITARY, CLASS_PLAYER. Besides this all the ships flying in a group like pirates, police or escorts get an "ATTACKED" message as when they were attacked themself.
broadcastDistressMessage Locates all the stations, bounty hunters and police ships in range and tells them that you are under attack. This command resets a previous found target to none at the sending side. It returns: "ACCEPT_DISTRESS_MESSAGE" in the AI of Stations, Hunters and Police ships and gives them as" Found Target", the "Primary Target" of the sender of the broadcast.
commsMessage:(NSString *)valueString Broadcasts a general message to player. It will only send a message if the ship has a pilot. (not by rocks, cargo pods etc.)

Example:

"sendCommsMessage: [thargoid_curses]"
commsMessageByUnpiloted:(NSString *)valueString Broadcasts a general message to player without check for pilot. (Will be available from 1.72+)

Example:

"commsMessageByUnpiloted: This is an automated distress signal."
patrolReportIn This command sets the "last patrol report time" to the current time. Only useful for station patrol.
sendTargetCommsMessage:(NSString*) message Sends any message to the established (found) target. When the target is not a ship it returns: "TARGET_LOST"

Example:

"sendTargetCommsMessage: Listen to me!!"

Locating entities

All these methods require a range to be set by setDesiredRange or by <scanner_range> in shipdata.plist, all will return the message TARGET_FOUND or NOTHING_FOUND. The calling entity remembers the found target, but it does not become the current (universal) target. It can be made the current target by responding to the TARGET_FOUND message with a call to setTargetToFoundTarget.

When you are continuously scanning as in a update event, make sure you add also a pause command. Scanning takes time and in most cases one scan every few seconds is enough. Look also at Oolites internal AI's were this timing is well thought of.

Method Description
checkCourseToDestination Will return "COURSE_OK" when no obstacles on the direct route, else it calculates a little deviated save vector and returns "WAYPOINT_SET". When there is a small ship in his way it also returns: HAZARD_CAN_BE_DESTROYED
checkDistanceTravelled First you must define a range with setDesiredRangeTo:. When the total traveled distance since creation is greater than this value it returns: "GONE_BEYOND_RANGE". Used for missiles.
checkGroupOddsVersusTarget Will return "ODDS_GOOD", "ODDS_LEVEL" or "ODDS_BAD".
checkForFullHold If entity's cargo capacity is reached, will return "HOLD_FULL".
checkForMotherStation Will return "STATION_FOUND" or "NOTHING_FOUND".
checkForNormalSpace Will return "NORMAL_SPACE" or "INTERSTELLAR_SPACE".
checkTargetLegalStatus Returns "TARGET_CLEAN, "TARGET_MINOR_OFFENDER", "TARGET_OFFENDER", "TARGET_FUGITIVE" or "NO_TARGET".
findNearestPlanet Will scan for planetentity. Returns nothing. Nearest planet coordinates are placed in destination memory.
scanForFormationLeader Locates the nearest suitable formation leader in range. Returns: "TARGET_FOUND" or "NOTHING_FOUND". See also Escort Instructions.
scanForHostiles Locates all the ships in range targeting the receiver and ships with "SCANNCLASS_TARGOID" and chooses the nearest. Returns: "TARGET_FOUND" or "NOTHING_FOUND"
scanForLoot Scans for nearest debris in range.

Returns: "HOLD_FULL", "TARGET_FOUND" or "NOTHING_FOUND". If scanning ship is moving station or has no scoop it always return: "NOTHING_FOUND". If scanning ship has scanClass: "CLASS_POLICE", it only finds slaves and lifepods.

scanForNearestMerchantmen Scans for ships with role: Trader or Player and selects the nearest. If scanning ship has role Pirate it prefers the player.

Returns: "TARGET_FOUND" or "NOTHING_FOUND"

scanForNearestShipWithRole:(NSString*) scanRole Locates all the ships in range and chooses the nearest. Returns: "TARGET_FOUND" or "NOTHING_FOUND"
scanForNonThargoid Locates all the non thargoid ships in range and chooses the nearest. It finds everything except cargo and ships with a role starting with: "tharg". If it finds the player it prefers the player. Returns: "TARGET_FOUND" or "NOTHING_FOUND"
scanForOffenders Locates all the ships in range, subtracts a random value between 0 and 255 from their legal status or bounty and compares the remaining value. It chooses the worst offender. Because of the random value not all ships are found in every scan and the lower the bounty the longer it takes to detect him as offender. Returns: "TARGET_FOUND" or "NOTHING_FOUND"
scanForRandomLoot Scans for debris in range and selects one at random from the first 16 found.

Returns: "HOLD_FULL", "TARGET_FOUND" or "NOTHING_FOUND" If scanning ship is station or has no scoop it always return: "NOTHING_FOUND".

scanForRandomMerchantmen Scans for ships with role: Trader or Player and selects one at random. Returns: "TARGET_FOUND" or "NOTHING_FOUND".
scanForRocks Scans for nearest boulder in range. When nothing found then scans for nearest asteroid in range. Returns "TARGET_FOUND" or "NOTING_FOUND".
scanForThargoid Locates all the ships with role "thargoid" in range and chooses the nearest. Returns: "TARGET_FOUND" or "NOTHING_FOUND"

Targeting

Method Description
requestNewTarget Locates all the ships in range targeting the mother ship, and chooses the nearest/biggest. Returns: "MOTHER_LOST", "TARGET_FOUND" or "NOTHING_FOUND".
setTargetToFoundTarget Affirms a TARGET_FOUND by a scanFor- or find-Something-method as the universal target.
setTargetToPrimaryAggressor This function sets the primary agressor to the primary target. Then in the "performAttack" state, it only has a 25% change of setting the primary agressor to the primary target. The other 75% it will do nothing. This function is designed for used during attack to prevent it will constantly change targets when attacking a group.

primary agressor is set by the system when a ship fires a laser or missile on the other.

Miscellaneous

Method Description
addFuel:(NSString*) fuel_number Changes player's fuel level by fuel_number LY's, max to 7.0 min to 0.0.
becomeUncontrolledThargon Changes ship into cargo with scannClass "CLASS_CARGO" and sets AI to "dumbAI". If also the the cargo type is defined in ShipData.plist it can be picked up like any other cargo.
initialiseTurret Prepares the turret. As turrets have no statemachine of their own, this function can only be used in the setup_actions of the turrets shipData.
rollD:(NSString*) dice_number Uses "dice" for random situation use. It returns "ROLL_1", "ROLL_2" and so on until dice_number. dice_number is an integer and has no size limit.

Example 1, 3 options in someAI.plist:

GLOBAL = {
  ENTER = ("rollD: 3"); 
  "ROLL_1" = (action1);
  "ROLL_2" = (action2);
  "ROLL_3" = (action3);}

Example 2, 50% chance in script.plist;

conditions = ("d100_number lessthan 50");
do = (action1);
else = (action2);

is similar in function.

safeScriptActionOnTarget:(NSString*) action This will do a script action on the target. For NPC ships as target you can use all the AI commands available that will act as if its own AI used the command. (command introduced with version 1.71)

It will also execute player script commands, like setting mission variables. For this to work it needs a target being set. It doesn't matter witch one.

Example:

"scriptActionOnTarget: set: mission_my_missionvariable TRUE",
"scriptActionOnTarget: awardCredits: 100"
scriptActionOnTarget:(NSString*) action This will do the same as safeScriptActionOnTarget, but in addition the legacy script engine is started so all installed player scripts are evaluated immediately. Use of this command is discouraged in favour of safeScriptActionOnTarget as it takes a lot of time to evaluate all scripts and in most situations this is also unnecessary.
sendScriptMessage: message Calls the javaScript function message() on the ship’s ship script. Added in Oolite 1.70. This function opens the whole js power to the AI scripting.

Role scanning methods

Starting with version 1.70 next commands will become available. This info is still preliminary until the actual release.

Method Description
scanForNearestShipWithPrimaryRole:(NSString*) role new (preferred) name for scanForNearestShipWithRole:.
scanForNearestShipHavingRole:(NSString*) role scan based on entire role set rather than primary role.
scanForNearestShipWithAnyPrimaryRole:(NSString*) role-list takes a list of roles (space-separated) and returns the nearest ship with any of them as primary.
scanForNearestShipHavingAnyRole:(NSString*) role-list takes a list of roles (space-separated) and returns the nearest ship with any of them in its role set.
scanForNearestShipWithScanClass:(NSString*) scanclass searches for a ship by scan class.
scanForNearestShipWithoutPrimaryRole:(NSString*) role
scanForNearestShipNotHavingRole:(NSString*) role
scanForNearestShipWithoutAnyPrimaryRole:(NSString*) role-list
scanForNearestShipNotHavingAnyRole:(NSString*) role-list
scanForNearestShipWithoutScanClass:(NSString*) scanclass
setPrimaryRole:(NSString*) role Sets the primary role for a ship.