Quests API

Query quest completion status, progress, and information.

Constants

quests.Quest

Quest enum for type-safe quest selection. All quest constants follow the SCREAMING_SNAKE_CASE format.

quests.Quest.COOKS_ASSISTANT           -- "COOKS_ASSISTANT"
quests.Quest.DRAGON_SLAYER_I           -- "DRAGON_SLAYER_I"
quests.Quest.RECIPE_FOR_DISASTER       -- "RECIPE_FOR_DISASTER"
quests.Quest.THE_FREMENNIK_TRIALS      -- "THE_FREMENNIK_TRIALS"
quests.Quest.ANIMAL_MAGNETISM          -- "ANIMAL_MAGNETISM"

Example:

-- Use enum for type safety (recommended)
if quests:is_completed(quests.Quest.COOKS_ASSISTANT) then
    logger:info("Cook's Assistant is complete!")
end

-- String literals also work (case-insensitive, backward compatible)
quests:is_completed("cooks assistant")
quests:is_completed("Cook's Assistant")

See Quest Constants section below for a complete list.


Functions

points

quests:points() -> number

Get total quest points earned by the player.

Returns:

  • number - Total quest points

Example:

local qp = quests:points()
logger:info("Quest points: " .. qp)

completed

quests:completed() -> table

Get array of completed quest constant names.

Returns:

  • table - Array of quest constant name strings (e.g., "COOKS_ASSISTANT")

Example:

local completed = quests:completed()
logger:info("Completed " .. #completed .. " quests")
for _, quest_name in ipairs(completed) do
    logger:info("  - " .. quest_name)
end

-- Check if specific quest is in completed list
local has_barrows = false
for _, quest in ipairs(completed) do
    if quest == quests.Quest.PRIEST_IN_PERIL then
        has_barrows = true
        break
    end
end

started

quests:started() -> table

Get array of started (but not completed) quest constant names.

Returns:

  • table - Array of quest constant name strings

unstarted

quests:unstarted() -> table

Get array of unstarted quest constant names.

Returns:

  • table - Array of quest constant name strings

free_quests

quests:free_quests() -> table

Get array of all free-to-play quest constant names.

Returns:

  • table - Array of F2P quest constant name strings

members_quests

quests:members_quests() -> table

Get array of all members-only quest constant names.

Returns:

  • table - Array of P2P quest constant name strings

is_completed

quests:is_completed(quest_name: string) -> boolean

Check if a specific quest is completed.

Parameters:

ParameterTypeRequiredDescription
quest_namestringYesQuest name (use quests.Quest.QUEST_NAME)

Returns:

  • boolean - True if completed

Example:

if quests:is_completed(quests.Quest.COOKS_ASSISTANT) then
    logger:info("Cook's Assistant completed!")
end

is_started

quests:is_started(quest_name: string) -> boolean

Check if a specific quest has been started but not completed.

Parameters:

ParameterTypeRequiredDescription
quest_namestringYesQuest name

Returns:

  • boolean - True if started (but not completed)

state

quests:state(quest_name: string) -> number

Get the current state value for a quest (varbit/varplayer value).

Parameters:

ParameterTypeRequiredDescription
quest_namestringYesQuest name

Returns:

  • number - Quest state value (0 if quest not found)

Example:

local state = quests:state(quests.Quest.DRAGON_SLAYER_I)
logger:info("Dragon Slayer I progress: " .. state)

info

quests:info(quest_name: string) -> table?

Get detailed information about a quest.

Parameters:

ParameterTypeRequiredDescription
quest_namestringYesQuest name

Returns:

  • table or nil - Quest info table with fields:
    • name (string) - Quest display name
    • members_only (boolean) - True if members quest
    • quest_points (number) - Quest points awarded
    • state (number) - Current quest state value
    • completed (boolean) - True if completed
    • started (boolean) - True if started

Example:

local info = quests:info(quests.Quest.RECIPE_FOR_DISASTER)
if info then
    logger:info("Quest: " .. info.name)
    logger:info("Points: " .. info.quest_points)
    logger:info("Completed: " .. tostring(info.completed))
end

all_names

quests:all_names() -> table

Get array of all quest names in the game.

Returns:

  • table - Array of all quest name strings

Quest Constants

Available quests (use quests.Quest.QUEST_NAME):

F2P Quests

  • BLACK_KNIGHTS_FORTRESS
  • COOKS_ASSISTANT
  • DEMON_SLAYER
  • DORICS_QUEST
  • DRAGON_SLAYER_I
  • ERNEST_THE_CHICKEN
  • GOBLIN_DIPLOMACY
  • IMP_CATCHER
  • THE_KNIGHTS_SWORD
  • PIRATES_TREASURE
  • PRINCE_ALI_RESCUE
  • THE_RESTLESS_GHOST
  • ROMEO_AND_JULIET
  • RUNE_MYSTERIES
  • SHEEP_SHEARER
  • SHIELD_OF_ARRAV
  • VAMPYRE_SLAYER
  • WITCHS_POTION
  • X_MARKS_THE_SPOT
  • BELOW_ICE_MOUNTAIN
  • THE_CORSAIR_CURSE

Popular P2P Quests

  • ANIMAL_MAGNETISM
  • DESERT_TREASURE_I
  • DRAGON_SLAYER_II
  • FAIRYTALE_II_CURE_A_QUEEN
  • HEROES_QUEST
  • LEGENDS_QUEST
  • LOST_CITY
  • LUNAR_DIPLOMACY
  • MONKEY_MADNESS_I
  • MONKEY_MADNESS_II
  • RECIPE_FOR_DISASTER
  • REGICIDE
  • SONG_OF_THE_ELVES
  • UNDERGROUND_PASS
  • WATERFALL_QUEST

All Quest Constants (181 total)

Use quests:all_names() to get a complete list, or access directly:

quests.Quest.COOKS_ASSISTANT           -- "Cook's Assistant"
quests.Quest.DRAGON_SLAYER_I           -- "Dragon Slayer I"
quests.Quest.RECIPE_FOR_DISASTER       -- "Recipe for Disaster"
quests.Quest.THE_FREMENNIK_TRIALS      -- "The Fremennik Trials"
quests.Quest.MOURNINGS_END_PART_II     -- "Mourning's End Part II"

Common Patterns

Check Quest Prerequisites

local function has_rfd_requirements()
    -- Check all Recipe for Disaster sub-quests
    local required = {
        quests.Quest.COOKS_ASSISTANT,
        quests.Quest.FISHING_CONTEST,
        quests.Quest.GOBLIN_DIPLOMACY,
        quests.Quest.BIG_CHOMPY_BIRD_HUNTING,
        quests.Quest.MURDER_MYSTERY,
        quests.Quest.NATURE_SPIRIT,
        quests.Quest.WITCHS_HOUSE,
        quests.Quest.GERTRUDES_CAT,
        quests.Quest.SHADOW_OF_THE_STORM,
        quests.Quest.LEGENDS_QUEST
    }

    for _, quest in ipairs(required) do
        if not quests:is_completed(quest) then
            return false
        end
    end
    return true
end

Track Quest Progress

local function check_quest_progress()
    local qp = quests:points()
    local completed = quests:completed()
    local started = quests:started()

    logger:info("Quest Points: " .. qp .. "/300")
    logger:info("Completed: " .. #completed .. " quests")
    logger:info("In Progress: " .. #started .. " quests")

    -- Show quests in progress
    if #started > 0 then
        logger:info("Currently working on:")
        for _, quest_name in ipairs(started) do
            local state = quests:state(quest_name)
            logger:info("  " .. quest_name .. " (state: " .. state .. ")")
        end
    end
end

F2P Quest Completion Check

local function count_f2p_completed()
    local f2p = quests:free_quests()
    local count = 0

    for _, quest_name in ipairs(f2p) do
        if quests:is_completed(quest_name) then
            count = count + 1
        end
    end

    logger:info("F2P quests completed: " .. count .. "/" .. #f2p)
    return count
end

Quest State Machine

local function handle_dragon_slayer()
    local state = quests:state(quests.Quest.DRAGON_SLAYER_I)

    if state == 0 then
        logger:info("Quest not started - talk to Guildmaster")
    elseif state == 1 then
        logger:info("Get map pieces")
    elseif state == 2 then
        logger:info("Buy ship from Klarense")
    elseif state == 3 then
        logger:info("Repair ship and sail to Crandor")
    elseif state == 4 then
        logger:info("Kill Elvarg!")
    else
        logger:info("Quest completed!")
    end
end

Quest Point Goals

local function check_qp_milestones()
    local qp = quests:points()

    local milestones = {
        {points = 32, reward = "Dragon Slayer I"},
        {points = 100, reward = "Recipe for Disaster (100 QP requirement)"},
        {points = 175, reward = "Legends' Quest"},
        {points = 200, reward = "Quest Cape (200 QP minimum)"},
    }

    for _, milestone in ipairs(milestones) do
        if qp < milestone.points then
            logger:info("Next goal: " .. milestone.points .. " QP for " .. milestone.reward)
            logger:info("Need " .. (milestone.points - qp) .. " more QP")
            break
        end
    end
end

Related APIs

  • Skills API - Check skill requirements
  • Inventory API - Quest item management
  • NPCs API - Talk to quest NPCs
  • Movement API - Navigate to quest locations