The best way to avoid overly-complex AI's is to use 'stacked'AI's.
An AI(firstAI.plist) can stack another AI(secondAI.plist) on top of itself by calling the method 'setAITo: secondAI.plist'.
One could design a 'scaffoldAI' that defines the entity's default behaviour, have this call for specialised jobAI's when such specific behaviour is called for.
Specialised JobAI's need to 'exitAI' in order for the state machine to return to the previous AI.
(! Warning: do not use another 'setAITo' action to return to a previous state unless there is a good reason for doing so. To do so could lead to recursive AI loops, resulting in memoryleaks and crashes.)
Alternatively: the completion of a job results in the ending of the entity (leaves system or destruction for example). Entity death should exit all AI's in the stack.
Example of a multi-layer stacked AI-system:
defaultAI: Jobdescription: Navigate from witchpoint to station, ATTACKED = "setAITo: job1AI.plist"
job1AI: *STATE1 Jobdescription: Combat, scan for hostiles, attack. NO_TARGET = "set state to STATE2" *STATE2 Jobdescription: scanforloot/Attacked setStateTo:State1 NOTARGET = "exitAI" TARGETFOUND = "setAITo: job2AI.plist"
job2AI: *STATE1 jobdescription: performCollect (loot). NOTARGET = "exitAI"
Is the message recieved when a halted AI returns to the top of the stack.
So alternatively we could have organised the above system in a less complex way:
defaultAI: *STATE1 Jobdescription: Navigate from witchpoint to station, ATTACKED = ("setAITo: job1AI.plist"); RESTART = ("setStateTo: STATE2"); *STATE2 Jobdescription: scan for loot TARGET_FOUND = (setAITo: job2.plist"); ATTACKED = ("setAITo: job1AI.plist"); NO_TARGET = ("setStateTo: STATE1"); UPDATE = (scanForLoot);
job1AI: *STATE1 Jobdescription: combat; scanForHostiles,attack,etc. NO_TARGET = (exitAI)
job2AI: *STATE1 jobdescription: scanfor and collect loot. NO_TARGET = (exitAI) ATTACKED = ("setAITo: job1AI.plist");
The above examles have highly simplified AI scripts, for complete AI structure go here.
Working examples of JobAI are collectLootAI.plist and InterceptAI.plist.
A working example of a 'scaffold'AI is route1PatrollAI.plist.
OXP_howto OXP_howto_AI Back to: State_machine