AI Framework

From The DarkMod Wiki
Revision as of 16:57, 26 September 2007 by Greebo (talk | contribs)
Jump to navigationJump to search

AI Priority Queue Basics

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).

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, in this case, the method is

void ai_darkmod_base::task_Idle().

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.

Note that the currently executed task is not listed in the priority queue.

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. An example for such a "self-pushing" task is task_Idle().

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