Questie (3.3.5a)

Developer documentation for Project Ascension & Project Ebonhold compatibility layers and core engine refinements.

Version: v9.9.0 Branch: feature/ebonhold-compat View Changelog

Ebonhold Database Architecture

To support custom servers without polluting the base WotLK database, Questie now implements a modular override system. This allows custom quests, NPCs, and objects to be defined in a safe namespace that persists across upstream updates.

1. Directory Structure

Database/Ebonhold/
├── EbonholdLoader.lua       # Main injection hook
├── Zones/
│   └── EbonholdZoneTables.lua # Custom AreaID/MapID mappings
└── Ebonhold/
    ├── EbonholdQuestDB.lua  # Custom Quest definitions
    └── EbonholdNpcDB.lua    # Custom NPC spawn overrides

2. Injection Methodology

The system hooks into QuestieDB:Initialize(). Instead of modifying QuestieDB.questData directly, it populates the override tables which are checked during quest retrieval.

-- EbonholdLoader.lua snippet
local function InjectOverrides()
    for id, data in pairs(EbonholdDB.questData) do
        QuestieDB.questDataOverrides[id] = data
    end
end

Core Logic Refinements

Quest Arrow: Auto-Mode

Restored "Auto Nearby" logic which points to the closest available quest when the player has no active tracking list. Features Zone Filtering to prevent the arrow from pointing to distant continents when in auto-mode.

Tracker Robustness

The tracker update loop is now protected with pcall. This prevents malformed quest data (like the "Fel Orc Scavengers" bug) from crashing the entire UI and hiding unrelated quests.

Quest Icon Persistence Fix

Custom server quests often use auto-complete triggers which can bypass Questie's standard cleanup events. I implemented a two-tier cleanup strategy:

Custom Quest Implementation

For large-scale "kill count" quests (e.g., 75 Dragonkin), I utilize the killCreditObjective pattern. This allows a single quest objective to be mapped to a dynamic list of NPC IDs.

Developer Note: Using killCreditObjective (Index [10][5]) ensures that all participating NPC spawns appear on the map, but only one counter appears in the tracker.
-- Example implementation (EbonholdQuestDB.lua)
[50064] = {
    [1] = "Heart of the Dragonflights",
    [10] = {
        nil, nil, nil, nil,
        { -- killCreditObjective
            {
                { 26276, 26277, 26322, ... }, -- All NPC IDs
                26322,                       -- Root ID (Icon/Text)
                "Dragonkin slain"            -- Display Text
            }
        }
    },
    [30] = 30, -- Objective Count
}