[Show Table of Contents]

The concept of Task Sets was intended to make it a bit easier to write quest NPCs that can offer a lot of tasks.


The system is governed by two database tables:

§Tasksets Table

CREATE TABLE `tasksets` (
  `id` int(11) unsigned NOT NULL,
  `taskid` int(11) unsigned NOT NULL,
  PRIMARY KEY  (`id`,`taskid`)

§Character Enabled Tasks Table

CREATE TABLE `character_enabledtasks` (
  `charid` int(11) unsigned NOT NULL,
  `taskid` int(11) unsigned NOT NULL,
  PRIMARY KEY  (`charid`,`taskid`)

The first table contains the Task Sets themselves, so, if you wanted to create new Task Set, say Task Set number 10, contained Tasks 50 to 89, you would create 40 rows, (10, 50), (10, 51), (10, 52) etc.

In your Perl quest, to offer this set of tasks to the player, you would call quest::tasksetselector(10).

The table character_enabledtasks controls which tasks in a taskset a character is permitted to select. When tasksetselector(10) is called, the contents of the character_enabledtasks table is compared to Task Set 10, and only tasks for which the character has an entry in character_enabledtasks will be listed in the Task Selector window.

When a character is created, the character_enabledtasks table is empty.

Let's say Task Set contains progressively harder tasks that are to be unlocked as the player completes earlier tasks.

The first time the player encounters your quest NPC, it could check if the character has any enabled tasks in the progression, and if not, enable the first three:

if(quest::enabledtaskcount(10) == 0) {
        quest::enabletask(50, 51, 52);
  • There are different ways that the unlocking of further tasks could be handled. For example, the last activity in task 52 could be to talk to this same NPC. You could then unlock the next 3 tasks:
# Activity 8 is the last step of task 52, talk to this NPC
        if(quest::istaskactivityactive(52, 8)) {
# Mark the task as complete
                quest::say("Well done. I see you are ready for further challenges.");

If you didn't want the character to be able to repeat a task on completion, you could use quest::disabletask.

Here is another example of using TaskSets:

# This example is based on a TaskSet (TaskSet 200), which consists of tasks 2000, 2001, 2002, 2003 and 2004
# The tasks are designed to be performed sequentially. Once one task is completed it cannot be selected again
# and the next task in the sequence is made available.
        quest::say("You accepted task $task_id");

        # If the player hasn't completed the last task in the TaskSet
        #$activecount = quest::activetasksinset(200);
        #$donecount = quest::completedtasksinset(200);
        #quest::say("You have $activecount active tasks and $donecount completed tasks in task set 200");
        if(!quest::istaskcompleted(quest::lasttaskinset(200))) {
                # If the player has no tasks enabled for this task set, enable the first one
                if(quest::enabledtaskcount(200) == 0) {
                        quest::say("You have not done any of my tasks before!");
                else {
                        # The player is enabled for a task in this TaskSet. Is he at the point
                        # in the task where he needs to speak to this NPC ?
                        $task = quest::activespeaktask();
                        if($task != 0) {
                                # If task != 0, then the player needs to speak to me, find out which activity it is
                                $activity = quest::activespeakactivity($task);
                                # Mark the activity as complete
                                #quest::say("Updating task $task activity $activity");
                                quest::updatetaskactivity($task, $activity);
                                quest::say("Well done!");
                                # If the task is now complete, offer the next task, if there is one
                                if(!quest::istaskactive($task)) {
                                        if($task != quest::lasttaskinset(200)) {
                                                quest::say("Well done, I have another task if you are willing.");
                                                quest::enabletask(quest::nexttaskinset(200, $task));
                                        else {
                                                quest::say("Thank you for cleansing Qeynos Hills!");
                        else {
                # Bring up the task selector, only if the player has no active tasks in this set.
                if(quest::activetasksinset(200) == 0) {
        else {
                quest::say("Hail, Hero of Qeynos!");

There are other ways of achieving this sort of progression without using Task Sets. For example you offer an initial task and on completion, you quest::assigntask the next one in the progression. If you adopt this approach, remember that the player can remove a task manually from their active task list, so you should consider whether you want the player to be able to reacquire the task without starting the progression again.

The complete list of Perl functions relating to TaskSets is:

  • enabletask
  • disabletask
  • istaskenabled
  • enabledtaskcount
  • tasksetselector
  • firsttaskinset
  • lasttaskinset
  • nexttaskinset
  • activetasksinset
  • completedtasksinset