Files

462 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Questie-X - Developer Documentation</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-primary: #0d1117;
--bg-secondary: #161b22;
--bg-tertiary: #21262d;
--text-primary: #c9d1d9;
--text-secondary: #8b949e;
--accent-green: #3fb950;
--accent-blue: #58a6ff;
--accent-purple: #a371f7;
--accent-orange: #d29922;
--border-color: #30363d;
--code-bg: #1b1f23;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
}
.hero {
background: linear-gradient(135deg, #1c2128 0%, #0d1117 100%);
padding: 80px 20px;
text-align: center;
border-bottom: 1px solid var(--border-color);
position: relative;
}
.hero h1 {
font-size: 3rem;
font-weight: 700;
margin-bottom: 15px;
background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero .subtitle {
font-size: 1.2rem;
color: var(--text-secondary);
max-width: 800px;
margin: 0 auto 30px;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 60px 20px;
}
section {
margin-bottom: 80px;
}
h2 {
font-size: 1.8rem;
margin-bottom: 30px;
padding-bottom: 10px;
border-bottom: 1px solid var(--border-color);
color: var(--accent-blue);
}
h3 {
font-size: 1.3rem;
margin: 30px 0 15px;
color: var(--text-primary);
}
p {
margin-bottom: 15px;
color: var(--text-secondary);
}
code {
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
background: var(--bg-tertiary);
padding: 2px 6px;
border-radius: 4px;
font-size: 0.9em;
}
pre {
background: var(--code-bg);
padding: 20px;
border-radius: 8px;
border: 1px solid var(--border-color);
overflow-x: auto;
margin: 20px 0;
}
pre code {
background: none;
padding: 0;
color: #e6edf3;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin: 30px 0;
}
.card {
background: var(--bg-secondary);
padding: 30px;
border-radius: 12px;
border: 1px solid var(--border-color);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.card:hover {
transform: translateY(-5px);
border-color: var(--accent-blue);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
background: var(--bg-tertiary);
}
.card::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(88, 166, 255, 0.05), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}
.card:hover::after {
opacity: 1;
}
.card h4 {
color: var(--accent-green);
margin-bottom: 15px;
font-size: 1.2rem;
display: flex;
align-items: center;
gap: 8px;
}
.important {
background: rgba(210, 153, 34, 0.05);
border: 1px solid rgba(210, 153, 34, 0.2);
border-left: 4px solid var(--accent-orange);
padding: 20px 25px;
margin: 30px 0;
border-radius: 8px;
color: var(--text-primary);
}
footer {
text-align: center;
padding: 60px 40px;
border-top: 1px solid var(--border-color);
color: var(--text-secondary);
font-size: 0.9rem;
background: var(--bg-secondary);
}
.file-path {
color: var(--accent-purple);
font-weight: 600;
}
.hero img {
filter: drop-shadow(0 0 20px rgba(88, 166, 255, 0.2));
transition: transform 0.5s ease;
}
.hero:hover img {
transform: scale(1.02);
}
@media (max-width: 768px) {
.grid {
grid-template-columns: 1fr;
}
.hero h1 {
font-size: 2.2rem;
}
}
</style>
</head>
<body>
<div class="hero">
<img src="QuestieXlogo.png" alt="Questie-X Logo" width="400" />
<p class="subtitle">A universal WoW quest-helper with a plugin architecture for any private server.</p>
<div style="display: flex; justify-content: center; gap: 10px;">
<code>Version: v1.6.3</code>
<a href="changelog.html"
style="background: var(--bg-tertiary); color: var(--accent-green); text-decoration: none; padding: 2px 6px; border-radius: 4px; font-size: 0.9em; border: 1px solid var(--border-color);">View
Changelog</a>
</div>
</div>
<div class="container">
<section id="active-performance-refactor">
<h2>Active Performance Refactor</h2>
<p>Questie-X is currently being refactored to reduce heavy-zone FPS drops. Until a stable release is published, testers should use the repository version rather than the release asset.</p>
<div class="grid">
<div class="card">
<h4>QuestieLearner Throttling</h4>
<p>Learner-triggered pin refreshes are now debounced with a maximum wait cap. Nearby-player <code>UNIT_DIED</code> events no longer force full learner pin redraws, while authoritative <code>PARTY_KILL</code> events are protected so local/group kills still learn correctly.</p>
</div>
<div class="card">
<h4>Advanced Performance Controls</h4>
<p>The Advanced tab now centralizes live QuestieLearner and QuestieComms tuning, including learner intensity, pin refresh delay, max refresh wait, live NPC update delay, comms disable, queue processing, broadcast pacing, and bulk sync pacing.</p>
</div>
</div>
<div class="grid">
<div class="card">
<h4>Arrow Throttles</h4>
<p>Arrow performance controls reduce repeated nearest-target and coordinate work for low-end systems while preserving the existing arrow behavior.</p>
</div>
<div class="card">
<h4>Branch Integration Status</h4>
<p>The latest learner/comms/arrow controls live on <code>questie-learner-comms-improvements</code>. Broader measured hot-path fixes live on <code>phase3-measured-perf</code>. A final integration branch is still required before stable release testing.</p>
</div>
</div>
<div class="important">
<strong>Testing focus:</strong> Validate heavy kill zones with the minimap open, nearby players killing mobs, looting stutter, QuestieComms disabled/low/normal/fast, and Arrow throttles adjusted live from the options menu.
</div>
</section>
<section id="release-highlights">
<h2>Current Release Highlights</h2>
<p>The v1.6.3 release includes the arrow redesign, the minimap pin alignment fix for non-1 UI scales, and the Sunstrider map and tooltip corrections. These notes summarize the shipped behavior in the live release.</p>
<div class="grid">
<div class="card">
<h4>Arrow Redesign</h4>
<p>The Arrow tab now ships with `Arrow1`-`Arrow4` as bundled image styles, keeps `arrowold` as the only sprite sheet, and lets users detach, lock, reattach, and preview custom arrow textures from `Icons/Arrows` without touching core files. Under the hood, the addon now distinguishes plain image TGAs from sprite sheets by texture format and alpha bounds, so only true sheets go through sheet-cell UV logic.</p>
</div>
<div class="card">
<h4>Sunstrider Coordinate Normalization (Final)</h4>
<p>Arrow and world-map code now normalize Sunstrider's child map <code>1241</code>, ghost map <code>946</code>, and parent Eversong map <code>1941</code> into a consistent coordinate path. <code>GetCurrentZoneId()</code> can return 3430 <em>or</em> 3431 on Sunstrider &mdash; all 4 detection checks now accept both values plus uiMapId 1241. The 1241&rarr;1941 redirect in <code>_ResolveMapUiMapId()</code> was removed; pins render natively on 1241 via <code>areaIdToUiMapId[1241] = 1241</code>.</p>
</div>
</div>
<div class="grid">
<div class="card">
<h4>Learned Tooltip Schema Fix</h4>
<p><code>QuestieTooltips</code> now reconstructs learned objective text from <code>QuestieLearner.data.quests[questId][10]</code> instead of treating learner arrays like legacy <code>{ questId -&gt; objList }</code> maps, preventing the Stormwind City Guard-style <code>objList</code>-as-number crash reported from Bronzebeard.</p>
</div>
<div class="card">
<h4>Arrow Rotation &amp; Collection Fixes</h4>
<p>Fixed arrow rotation direction (<code>SetRotation</code> is CW-positive, not CCW) and collection function distance mismatch where targets were converted through 1941 bounds while player coords were in 1241 bounds, causing 1261-yard errors instead of ~48 yards.</p>
</div>
<div class="card">
<h4>NPC Spawn Zone &amp; Native Map Pins</h4>
<p>NPC 15281 (Lanthan Perilon) spawn zone corrected from 3430 to 1241 so coords land in Sunstrider's 0-1 space. Pins on 1241 now render natively using Ascension-calibrated bounds with <code>areaIdToUiMapId[1241] = 1241</code> instead of redirecting to 1941.</p>
</div>
</div>
<div class="important">
<strong>Documentation scope:</strong> The landing page and changelog now describe the published v1.6.3 release state so collaborators can review what is currently shipped. The arrow notes here are intentionally developer-level: they call out the runtime split, the texture-format detection, and why the old sheet fallback only applies to <code>arrowold</code> or an explicitly custom sheet upload.
</div>
</section>
<!-- QuestieLearner Engine -->
<section id="questielearner">
<h2>QuestieLearner: Autonomous Data Engine</h2>
<p>Questie-X introduces <strong>QuestieLearner</strong>, a zero-configuration autonomous engine that learns the world as you play. It automatically bridges the gap between static database entries and real-time server-side realities.</p>
<div class="grid">
<div class="card">
<h4>Autonomous Acquisition</h4>
<p>Learns NPC spawns, Quest relationships, Object locations, and Item drops directly from combat logs and interaction events. No manual wiring or database entry required.</p>
</div>
<div class="card">
<h4>3.3.5a Coordinate Scaling</h4>
<p>Implements a precision-first scaling logic that normalizes 3.3.5a combat log coordinates (0-1) to Questie's 0-100 coordinate system, ensuring pixel-perfect map pins.</p>
</div>
</div>
<h3>Universal Cross-Link Engine</h3>
<p>A bidirectional relationship engine that automatically stitches connections between learned entities. If an item drops from an NPC for a specific quest, QuestieLearner cross-links all three, immediately enabling map pins and tooltips for that item-source chain.</p>
</section>
<!-- Data Integrity -->
<section id="integrity">
<h2>Data Integrity & Confidence</h2>
<p>To ensure database quality in crowd-sourced environments, Questie-X implements a multi-tier verification model.</p>
<div class="grid">
<div class="card">
<h4>Match Count (mc) System</h4>
<p>Every learned entry tracks its "Match Count". Data is promoted to <strong>Verified</strong> status once it reaches the user-defined confidence threshold (default: 2).</p>
</div>
<div class="card">
<h4>Stale Data Cleanup</h4>
<p>A tiered pruning engine tracks "Last Seen" (ls) timestamps. <strong>Unconfirmed</strong> data is automatically aged out after 90 days, while <strong>Verified</strong> entries are protected from expiration.</p>
</div>
</div>
<div class="important">
<strong>Confidence Gating:</strong> Map pins and tooltips for learned data are gated by confidence settings, preventing "one-off" anomalies or visual clutter from unconfirmed spawns.
</div>
</section>
<!-- Database Robustness -->
<section id="robustness">
<h2>Database Robustness &amp; Argument Handling</h2>
<p>Questie-X v1.5.0 introduces significant stability improvements to the core database lookup engine, ensuring compatibility with third-party plugins and malformed server data.</p>
<div class="grid">
<div class="card">
<h4>Polymorphic Argument Handling</h4>
<p>Lookup functions like <code>GetQuest</code>, <code>GetNPC</code>, and <code>GetItem</code> now support both numeric and string-based IDs, as well as colon-syntax calls (<code>QuestieDB:GetQuest</code>). This eliminates fatal errors caused by third-party plugins passing unformatted data.</p>
</div>
<div class="card">
<h4>Override Key Normalization</h4>
<p>The override system now performs dual-type lookups, checking both numeric and string keys for every entity. This guarantees that custom data from server-specific plugins is correctly resolved regardless of how IDs are stored internally.</p>
</div>
</div>
<div class="important">
<strong>Nil Guards:</strong> All core database accessors now feature strict guards against <code>nil</code> or <code>0</code> IDs, preventing "rawdata is nil" debug spam during heavy initialization phases on custom servers.
</div>
</section>
<!-- Zone Mapping & Performance -->
<section id="performance">
<h2>Zone Mapping &amp; Performance</h2>
<p>Questie-X v1.5.0 introduces a centralized mapping architecture to handle the complexities of custom server world data while optimizing memory usage.</p>
<div class="grid">
<div class="card">
<h4>Centralized Zone Mapping</h4>
<p>All AreaID to UiMapID relationships are now consolidated into the <code>QuestieX_WotLKDB</code> layer. This ensures that custom zones (seasonal, arena, or event maps) are immediately recognized by the coordinate engine without core modifications.</p>
</div>
<div class="card">
<h4>Memory Optimization</h4>
<p>By moving to a pre-compiled mapping constant, the engine avoids thousands of redundant table allocations during map sweeps, resulting in a 40% reduction in lookup overhead during peak quest-processing phases.</p>
</div>
</div>
<div class="important">
<strong>Compatibility First:</strong> This refactor restores pixel-perfect map pins on Project Ascension by bridging the gap between legacy zone IDs and modern UI map requirements at the earliest point of execution.
</div>
</section>
<!-- Infrastructure -->
<section id="infrastructure">
<h2>Network Infrastructure</h2>
<p>Questie-X utilizes hidden communication channels to synchronize confidence metrics and learned data across the player base in real-time.</p>
<div class="grid">
<div class="card">
<h4>Global Data Sync</h4>
<p>Learned kills and interactions are broadcasted via hidden global channels, allowing the community to effectively crowd-source the verification of spawn data.</p>
</div>
<div class="card">
<h4>Zero-Noise Heartbeat</h4>
<p>Communication is optimized to utilize hidden channels exclusively, ensuring zero impact on guild chat while maintaining real-time confidence updates.</p>
</div>
</div>
</section>
<!-- Database Architecture -->
<section id="database">
<h2>Ebonhold Database Architecture</h2>
<p>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.</p>
<h3>1. Directory Structure</h3>
<pre><code>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</code></pre>
<h3>2. Injection Methodology</h3>
<p>The system hooks into <code>QuestieDB:Initialize()</code>. Instead of modifying
<code>QuestieDB.questData</code> directly, it populates the override tables which are checked during
quest retrieval.
</p>
<pre><code>-- EbonholdLoader.lua snippet
local function InjectOverrides()
for id, data in pairs(EbonholdDB.questData) do
QuestieDB.questDataOverrides[id] = data
end
end</code></pre>
</section>
<!-- Custom Quest Implementation -->
<section id="custom-quests">
<h2>Custom Quest Implementation</h2>
<p>For large-scale "kill count" quests (e.g., 75 Dragonkin), I utilize the <code>killCreditObjective</code>
pattern. This allows a single quest objective to be mapped to a dynamic list of NPC IDs.</p>
<div class="important">
<strong>Developer Note:</strong> Using <code>killCreditObjective</code> (Index [10][5]) ensures that all
participating NPC spawns appear on the map, but only <strong>one</strong> counter appears in the
tracker.
</div>
<pre><code>-- 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
}</code></pre>
</section>
</div>
<footer>
<p>Maintained by Xurkon</p>
<div style="margin-top: 15px; display: flex; justify-content: center; gap: 10px;">
<a href="https://www.patreon.com/Xurkon" target="_blank">
<img src="https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white" alt="Patreon" height="28">
</a>
<a href="https://www.paypal.me/Xurkon" target="_blank">
<img src="https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white" alt="PayPal" height="28">
</a>
</div>
</footer>
</body>
</html>