AI Framework: Difference between revisions

From The DarkMod Wiki
Jump to navigationJump to search
Replacing page with '== AI Priority Queue == Please refer to this article for documentation about the priority queue scripts: AI Priority Queue Category:AI Category:Scripting [[Cat...'
Line 1: Line 1:
== AI Priority Queue Basics ==
== [[AI Priority Queue]] ==
Each AI state (idle, combat, etc.) corresponds to a task with an associated priority. For instance, the idle task has a priority of 1000. It's possible to push several different tasks into an AI's task queue, but only the task with the highest priority value will get executed (this is handled by the SDK).
Please refer to this article for documentation about the priority queue scripts: [[AI Priority Queue]]


Let's say our AI is in "idle" state (which means that no higher-prioritized tasks are pending): the SDK will lookup the according method from the AI's scriptobject (and pop the task from the queue). In this case, the method is
[[Category:AI]]
'''void ai_darkmod_base::task_Idle()'''.
[[Category:Scripting]]
 
[[Category:Coding]]
A task is considered finished or done when the script method is returning. As long as the method is running (e.g. with an '''eachFrame''' loop), the task is not considered done. However, the task is terminated by the SDK as soon as a higher-prioritised one is available in the queue.
 
Note that the currently executed task is not listed in the priority queue. It gets popped (removed) from the queue before the corresponding script function is executed.
 
=== Switching Tasks / Task Lifetime ===
The SDK code always switches to the task with the highest priority, whether the currently active task is finished or not. The script thread is pointed to the new task and the old one is practically terminated (the stack is cleared). Hence, if you push a task with a higher priority than the current one, the higher rated one is being executed in the next frame (at the latest), whether you call return or not. If a task's intention is to be active again after the high-priority task is finished, it must push itself too - the SDK code won't come back to this task on its own. '''Pushing a higher-prioritised task implies to terminate the current one''' (at the next frame at the latest). An example for such a "self-pushing" task is '''task_Idle()'''.
 
=== Maximum Switches per Frame ===
As long as no other higher prioritised task is available, the current one gets executed each frame by the SDK. When a higher-priority task gets pushed, the script thread switches to that one. This is called ''switching tasks''.
 
Let's assume the task being switched to pushes another higher-prioritised one and immediately returns. As expected, this triggers another task switch, ''in the same frame''. To avoid a series of task switching operations blocking the SDK code, the maximum number of task switches is constrained to 19. When this number is exhausted (which should be unlikely in most situations), the highest prioritised task is executed in the next frame instead.
 
== How to add/switch Tasks ==
Let's say an AI is in idle state and encounters an enemy which it likes to fight. To switch to "fighting mode", the '''task_Combat''' must be pushed to the priority queue, which can be done like this (pseudocode):
void task_Idle()
{
  eachFrame {
    if (enemyCanBeSeen) {
      pushTask("task_Combat", PRIORITY_COMBAT); // Register a new task (with the (higher) combat priority)
      return; // return means to end this "idle" task, but it will be terminated soon enough anyway
    }
   
    // Perform regular idle tasks (patrolling, head turning, talking, whatever).
  }
}
 
== Cleanup Tasks ==
Let's assume a higher-prioritised task is available and the SDK is about to switch to the new script function. As just terminating the currently active thread might be considered bad manners, the SDK gives the current thread a chance to cleanly shutdown by looking for a cleanup task. The cleanup script function can be defined by adding a ''_cleanup'' postfix to the function's name. In the case of the task_Idle script method, this would be
void ai_darkmod_base::task_Idle_cleanup(); // the cleanup task corresponding to task_Idle()
                                            // gets executed before switching to another task
Defining such a cleanup task is completely optional. If it has been omitted, the SDK switches right to the higher-prioritised task.
 
[[Category:AI Coding]]

Revision as of 17:14, 26 September 2007

AI Priority Queue

Please refer to this article for documentation about the priority queue scripts: AI Priority Queue