WoW Addon Entwicklung - Komplette Referenz
Link zum Projekt: GitHub - WoW Addons
Umfassende deutschsprachige Dokumentation für die World of Warcraft Addon-Entwicklung mit Fokus auf TBC/Classic.
Inhaltsverzeichnis
- Erste Schritte
- Addon-Struktur & TOC-Datei
- Lua Grundlagen
- Event-System
- Widget API - UI Elemente
- Häufige API-Funktionen
- Slash-Befehle
- SavedVariables - Persistente Daten
- XML UI Layout
- Secure Templates & Combat Lockdown
- TBC Classic Besonderheiten
- Ressourcen
Erste Schritte
Was du brauchst
- Texteditor: VS Code, Notepad++, Sublime Text
- WoW Client: Classic/TBC installiert
- Grundkenntnisse: Keine Programmiererfahrung nötig
Addon-Speicherort
World of Warcraft\_classic_\Interface\AddOns\DeinAddonName\
Dein erstes Addon
1. Ordner erstellen: Interface\AddOns\HalloWelt\
2. TOC-Datei erstellen (HalloWelt.toc):
## Interface: 11508
## Title: Hallo Welt
## Notes: Mein erstes Addon!
## Author: DeinName
## Version: 1.0.0
HalloWelt.lua
3. Lua-Datei erstellen (HalloWelt.lua):
local frame = CreateFrame("Frame")
frame:RegisterEvent("PLAYER_LOGIN")
frame:SetScript("OnEvent", function(self, event)
print("Hallo, Welt!")
end)
4. Addon laden: /reload im Spiel eingeben
Entwicklungswerkzeuge
| Befehl | Beschreibung |
|--------|--------------|
| /reload | UI neu laden |
| /dump ausdruck | Lua-Ausdruck auswerten |
| /etrace | Event-Trace-Fenster |
| /fstack | Frame-Stack-Inspektor |
Addon-Struktur & TOC-Datei
Typische Ordnerstruktur
MeinAddon/
├── MeinAddon.toc # Pflicht: Addon-Manifest
├── MeinAddon.lua # Haupt-Code-Datei
├── Config.lua # Einstellungen
├── embeds.xml # Bibliotheks-Includes
├── libs/ # Externe Bibliotheken
└── Locales/ # Lokalisierung
TOC-Datei Format
## Interface: 11508
## Title: Mein Addon
## Notes: Beschreibung des Addons
## Author: Dein Name
## Version: 1.0.0
## SavedVariables: MeinAddonDB
## SavedVariablesPerCharacter: MeinAddonCharDB
## OptionalDeps: Ace3
embeds.xml
Core.lua
Config.lua
Wichtige TOC-Direktiven
| Direktive | Beschreibung |
|-----------|--------------|
| Interface | Client-Version |
| Title | Anzeigename in der Addon-Liste |
| Notes | Beschreibung als Tooltip |
| SavedVariables | Account-weite gespeicherte Daten |
| SavedVariablesPerCharacter | Pro-Charakter-Daten |
| Dependencies | Benötigte Addons |
| OptionalDeps | Optionale Abhängigkeiten |
| LoadOnDemand | Bei Bedarf laden (1 = ja) |
Interface-Versionen
| Client | Version |
|--------|---------|
| Classic Era/Anniversary | 11508 |
| TBC Classic | 20504 |
| Wrath Classic | 30403 |
| Cataclysm Classic | 40400 |
Aktuelle Version prüfen: /dump select(4, GetBuildInfo())
Lua Grundlagen
Variablen
-- Lokale Variable (bevorzugt)
local meinWert = "Hallo"
-- Globale Variable (vermeiden wenn möglich)
MeineGlobaleVar = "Welt"
-- Datentypen
local text = "String" -- Text
local zahl = 100 -- Zahl
local dezimal = 0.75 -- Dezimalzahl
local aktiv = true -- Boolean
local nichts = nil -- Nil (kein Wert)
local tabelle = {1, 2, 3} -- Array
local dict = {name = "Held"} -- Dictionary
Operatoren
-- Arithmetik
local a = 10 + 5 -- 15
local b = 10 - 5 -- 5
local c = 10 * 5 -- 50
local d = 10 / 5 -- 2
local e = 10 % 3 -- 1 (Modulo)
-- Vergleich
a == b -- gleich
a ~= b -- ungleich (NICHT !=)
a < b -- kleiner
a > b -- größer
-- Logisch
true and false -- false
true or false -- true
not true -- false
-- String-Verkettung
"Hallo" .. " " .. "Welt" -- "Hallo Welt"
Kontrollstrukturen
-- If/Else
local leben = UnitHealth("player")
if leben > 50 then
print("Alles gut")
elseif leben > 25 then
print("Vorsicht!")
else
print("Kritisch!")
end
-- Ternärer Stil (Lua-Idiom)
local status = (leben > 50) and "Gut" or "Schlecht"
Schleifen
-- For-Schleife (numerisch)
for i = 1, 10 do
print(i)
end
-- For-Schleife (Array)
local items = {"Schwert", "Schild", "Trank"}
for index, item in ipairs(items) do
print(index, item)
end
-- For-Schleife (Dictionary)
local stats = {staerke = 100, beweglichkeit = 50}
for key, value in pairs(stats) do
print(key, value)
end
-- While-Schleife
local count = 0
while count < 5 do
print(count)
count = count + 1
end
Funktionen
-- Einfache Funktion
local function gruessen(name)
print("Hallo, " .. name)
end
gruessen("Spieler")
-- Funktion mit Rückgabe
local function addieren(a, b)
return a + b
end
local summe = addieren(5, 3) -- 8
-- Mehrere Rückgabewerte
local function getSpielerInfo()
return "Spielername", 60, "Krieger"
end
local name, level, klasse = getSpielerInfo()
-- Anonyme Funktion
frame:SetScript("OnClick", function(self, button)
print("Geklickt mit:", button)
end)
Tabellen
-- Array (1-indiziert!)
local items = {"Schwert", "Schild"}
print(items[1]) -- "Schwert"
print(#items) -- 2 (Länge)
table.insert(items, "Trank")
table.remove(items, 1)
-- Dictionary
local spieler = {
name = "Held",
level = 60,
klasse = "Krieger"
}
print(spieler.name) -- "Held"
print(spieler["level"]) -- 60
-- Tabelle als Objekt
local MeinAddon = {}
function MeinAddon:Initialisieren()
self.aktiv = true
end
MeinAddon:Initialisieren()
Event-System
Grundlegendes Event-Handling
-- 1. Frame erstellen
local frame = CreateFrame("Frame")
-- 2. Events registrieren
frame:RegisterEvent("PLAYER_LOGIN")
frame:RegisterEvent("PLAYER_LOGOUT")
-- 3. Event-Handler setzen
frame:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_LOGIN" then
print("Spieler eingeloggt!")
elseif event == "PLAYER_LOGOUT" then
print("Spieler loggt aus!")
end
end)
Event-Handler Parameter
| Parameter | Beschreibung |
|-----------|--------------|
| self | Der empfangende Frame |
| event | Event-Name (String) |
| ... | Event-spezifische Argumente |
Event-Registrierung
frame:RegisterEvent("UNIT_HEALTH")
frame:UnregisterEvent("UNIT_HEALTH")
frame:UnregisterAllEvents()
-- Unit-spezifisches Event
frame:RegisterUnitEvent("UNIT_HEALTH", "player", "target")
Wichtige Events
Login/Logout:
| Event | Beschreibung |
|-------|--------------|
| PLAYER_LOGIN | Spieler vollständig eingeloggt |
| PLAYER_LOGOUT | Spieler loggt aus |
| PLAYER_ENTERING_WORLD | Ladebildschirm beendet |
| ADDON_LOADED | Addon geladen (für SavedVariables) |
Kampf:
| Event | Beschreibung |
|-------|--------------|
| PLAYER_REGEN_DISABLED | Kampf beginnt |
| PLAYER_REGEN_ENABLED | Kampf endet |
| COMBAT_LOG_EVENT_UNFILTERED | Kampflog-Event |
| PLAYER_DEAD | Spieler gestorben |
Einheiten:
| Event | Argumente | Beschreibung |
|-------|-----------|--------------|
| UNIT_HEALTH | unitId | Leben geändert |
| UNIT_POWER_UPDATE | unitId, powerType | Kraft geändert |
| UNIT_AURA | unitId | Buffs/Debuffs geändert |
| UNIT_TARGET | unitId | Ziel geändert |
Gruppe:
| Event | Beschreibung |
|-------|--------------|
| GROUP_ROSTER_UPDATE | Gruppenzusammensetzung geändert |
| PARTY_MEMBER_ENABLE | Gruppenmitglied online |
Dispatch-Table-Pattern
local frame = CreateFrame("Frame")
local events = {}
function events:PLAYER_LOGIN()
print("Eingeloggt!")
end
function events:UNIT_HEALTH(unit)
if unit == "player" then
print("Leben:", UnitHealth("player"))
end
end
frame:SetScript("OnEvent", function(self, event, ...)
if events[event] then
events[event](self, ...)
end
end)
for event in pairs(events) do
frame:RegisterEvent(event)
end
Widget API - UI Elemente
Frame erstellen
-- CreateFrame(frameType, name, parent, template)
local frame = CreateFrame("Frame", "MeinFrame", UIParent)
frame:SetSize(200, 100)
frame:SetPoint("CENTER")
Häufige Frame-Typen
| Typ | Beschreibung |
|-----|--------------|
| Frame | Basis-Container |
| Button | Klickbarer Button |
| CheckButton | Checkbox |
| EditBox | Texteingabefeld |
| ScrollFrame | Scrollbarer Bereich |
| Slider | Schieberegler |
| StatusBar | Fortschrittsbalken |
Größe und Position
frame:SetSize(200, 100)
frame:SetWidth(200)
frame:SetHeight(100)
-- Ankerpunkte: TOPLEFT, TOP, TOPRIGHT, LEFT, CENTER, RIGHT, BOTTOMLEFT, BOTTOM, BOTTOMRIGHT
frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
frame:SetPoint("TOPLEFT", parentFrame, "BOTTOMLEFT", 10, -5)
frame:ClearAllPoints()
Sichtbarkeit
frame:Show()
frame:Hide()
frame:SetShown(true)
local isShown = frame:IsShown()
local isVisible = frame:IsVisible()
Texturen erstellen
-- Einfarbige Textur
local texture = frame:CreateTexture(nil, "BACKGROUND")
texture:SetAllPoints(frame)
texture:SetColorTexture(0, 0, 0, 0.8) -- RGBA
-- Bild-Textur
local icon = frame:CreateTexture(nil, "ARTWORK")
icon:SetSize(32, 32)
icon:SetPoint("LEFT", 5, 0)
icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
FontStrings (Text)
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
text:SetPoint("CENTER")
text:SetText("Hallo Welt")
text:SetTextColor(1, 1, 0) -- Gelb
Buttons
local button = CreateFrame("Button", "MeinButton", UIParent, "UIPanelButtonTemplate")
button:SetSize(100, 25)
button:SetPoint("CENTER")
button:SetText("Klick mich")
button:SetScript("OnClick", function(self, mouseButton, down)
print("Button geklickt mit:", mouseButton)
end)
StatusBar (Lebensbalken)
local bar = CreateFrame("StatusBar", nil, UIParent)
bar:SetSize(200, 20)
bar:SetPoint("CENTER")
bar:SetMinMaxValues(0, 100)
bar:SetValue(75)
bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
bar:SetStatusBarColor(0, 1, 0) -- Grün
Script-Handler
frame:SetScript("OnLoad", function(self) end)
frame:SetScript("OnShow", function(self) end)
frame:SetScript("OnHide", function(self) end)
frame:SetScript("OnUpdate", function(self, elapsed) end)
frame:SetScript("OnEvent", function(self, event, ...) end)
frame:SetScript("OnEnter", function(self) end)
frame:SetScript("OnLeave", function(self) end)
frame:SetScript("OnMouseDown", function(self, button) end)
frame:SetScript("OnMouseUp", function(self, button) end)
Häufige API-Funktionen
Unit IDs
| UnitId | Beschreibung |
|--------|--------------|
| player | Der Spieler |
| target | Aktuelles Ziel |
| focus | Fokus-Ziel |
| pet | Begleiter |
| party1-party4 | Gruppenmitglieder |
| raid1-raid40 | Schlachtzugmitglieder |
| mouseover | Einheit unter Mauszeiger |
| targettarget | Ziel des Ziels |
Unit-Funktionen
-- Grundinfos
local name = UnitName("target")
local level = UnitLevel("target")
local class, classFile = UnitClass("target") -- "Krieger", "WARRIOR"
local race = UnitRace("target")
local guid = UnitGUID("target")
-- Klassifikation
local classification = UnitClassification("target")
-- "normal", "elite", "rareelite", "rare", "worldboss"
-- Fraktion
local faction = UnitFactionGroup("target") -- "Horde", "Alliance"
local isEnemy = UnitIsEnemy("player", "target")
local isFriend = UnitIsFriend("player", "target")
-- Existenz prüfen
local exists = UnitExists("target")
local isPlayer = UnitIsPlayer("target")
local isSameUnit = UnitIsUnit("player", "target")
Leben und Kraft
-- Leben
local health = UnitHealth("player")
local maxHealth = UnitHealthMax("player")
local healthPercent = (health / maxHealth) * 100
-- Kraft (Mana, Wut, Energie)
local power = UnitPower("player")
local maxPower = UnitPowerMax("player")
local powerType = UnitPowerType("player")
-- 0=Mana, 1=Wut, 2=Fokus, 3=Energie
-- Tot?
local isDead = UnitIsDead("target")
local isGhost = UnitIsGhost("player")
Buff/Debuff-Funktionen
-- Buff nach Name
local name, icon, count, debuffType, duration, expirationTime =
UnitAura("player", "Segen der Macht", "HELPFUL")
-- Alle Buffs durchlaufen
for i = 1, 40 do
local name, _, _, _, _, _, source, _, _, spellId =
UnitAura("player", i, "HELPFUL")
if not name then break end
print(i, name, spellId)
end
-- Alle Debuffs durchlaufen
for i = 1, 40 do
local name = UnitAura("player", i, "HARMFUL")
if not name then break end
print(i, name)
end
Zauber-Funktionen
local name, rank, icon, castTime, minRange, maxRange = GetSpellInfo(spellId)
local start, duration, enabled = GetSpellCooldown(spellId)
local remaining = (start + duration) - GetTime()
local isKnown = IsSpellKnown(spellId)
Item-Funktionen
local name, link, quality, ilvl, reqLevel, class, subclass,
maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemId)
local count = GetItemCount(itemId)
local countMitBank = GetItemCount(itemId, true)
Chat-Funktionen
SendChatMessage("Hallo!", "SAY")
SendChatMessage("Gruppennachricht", "PARTY")
SendChatMessage("Schlachtzugnachricht", "RAID")
SendChatMessage("Flüstern", "WHISPER", nil, "Spielername")
SendChatMessage("Gildennachricht", "GUILD")
print("Nachricht")
DEFAULT_CHAT_FRAME:AddMessage("Rote Nachricht", 1, 0, 0)
Zeit-Funktionen
local time = GetTime() -- Sekunden, hohe Präzision
local hours, minutes = GetGameTime() -- Serverzeit
local formatted = date("%Y-%m-%d %H:%M:%S")
Gruppen-Funktionen
local numMembers = GetNumGroupMembers()
local inRaid = IsInRaid()
local inGroup = IsInGroup()
local name, rank, subgroup, level, class, fileName, zone,
online, isDead, role, isML = GetRaidRosterInfo(i)
Slash-Befehle
Einfacher Slash-Befehl
SLASH_MEINADDON1 = "/meinaddon"
SLASH_MEINADDON2 = "/ma"
SlashCmdList["MEINADDON"] = function(msg, editBox)
print("Befehl empfangen:", msg)
end
Argumente parsen
SLASH_MEINADDON1 = "/meinaddon"
SlashCmdList["MEINADDON"] = function(msg)
msg = msg:lower()
if msg == "" or msg == "hilfe" then
print("Nutzung: /meinaddon [an|aus|config|status]")
elseif msg == "an" then
MeinAddon.aktiv = true
print("MeinAddon aktiviert")
elseif msg == "aus" then
MeinAddon.aktiv = false
print("MeinAddon deaktiviert")
elseif msg == "config" then
MeinAddon:OpenConfig()
else
print("Unbekannter Befehl:", msg)
end
end
Mehrere Argumente
SlashCmdList["MEINADDON"] = function(msg)
local befehl, arg1, arg2 = strsplit(" ", msg, 3)
befehl = (befehl or ""):lower()
if befehl == "setze" and arg1 == "lautstaerke" and arg2 then
local wert = tonumber(arg2)
if wert and wert >= 0 and wert <= 100 then
MeinAddon.lautstaerke = wert
print("Lautstärke auf", wert, "gesetzt")
end
end
end
SavedVariables - Persistente Daten
Grundeinrichtung
1. In TOC deklarieren:
## SavedVariables: MeinAddonDB
## SavedVariablesPerCharacter: MeinAddonCharDB
2. In Lua initialisieren:
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, addonName)
if addonName == "MeinAddon" then
MeinAddonDB = MeinAddonDB or {}
MeinAddonDB.aktiv = MeinAddonDB.aktiv ~= false
MeinAddonDB.lautstaerke = MeinAddonDB.lautstaerke or 50
self:UnregisterEvent("ADDON_LOADED")
end
end)
Speicherorte
| Typ | Pfad |
|-----|------|
| Account-weit | WTF\Account\NAME\SavedVariables\Addon.lua |
| Pro-Charakter | WTF\Account\NAME\Realm\Char\SavedVariables\Addon.lua |
Standardwerte-Pattern
local defaults = {
aktiv = true,
lautstaerke = 50,
position = {x = 0, y = 0}
}
local function InitializeDB()
MeinAddonDB = MeinAddonDB or {}
for key, value in pairs(defaults) do
if MeinAddonDB[key] == nil then
if type(value) == "table" then
MeinAddonDB[key] = CopyTable(value)
else
MeinAddonDB[key] = value
end
end
end
end
AceDB-3.0 (Empfohlen)
local MeinAddon = LibStub("AceAddon-3.0"):NewAddon("MeinAddon", "AceConsole-3.0")
local defaults = {
profile = {
aktiv = true,
lautstaerke = 50,
},
char = {
position = {x = 0, y = 0}
}
}
function MeinAddon:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("MeinAddonDB", defaults, true)
print(self.db.profile.aktiv)
print(self.db.char.position.x)
end
Was gespeichert werden kann
| Unterstützt | Nicht unterstützt | |-------------|-------------------| | Strings | Funktionen | | Zahlen | Userdata (Frames) | | Booleans | Metatables | | Tabellen | | | nil | |
XML UI Layout
Basis-Struktur
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Core.lua"/>
<Include file="Frames.xml"/>
</Ui>
Frame-Definition
<Frame name="MeinFrame" parent="UIParent" enableMouse="true" movable="true">
<Size x="200" y="100"/>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<Texture setAllPoints="true">
<Color r="0" g="0" b="0" a="0.8"/>
</Texture>
</Layer>
<Layer level="OVERLAY">
<FontString name="$parentTitle" inherits="GameFontNormal">
<Anchors><Anchor point="CENTER"/></Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>self:RegisterForDrag("LeftButton")</OnLoad>
<OnDragStart>self:StartMoving()</OnDragStart>
<OnDragStop>self:StopMovingOrSizing()</OnDragStop>
</Scripts>
</Frame>
Layer-Ebenen
| Layer | Level | Beschreibung | |-------|-------|--------------| | BACKGROUND | 1 | Hintergrund | | BORDER | 2 | Rahmen | | ARTWORK | 3 | Hauptgrafik | | OVERLAY | 4 | Text, Icons | | HIGHLIGHT | 5 | Mouseover |
Button in XML
<Button name="MeinButton" inherits="UIPanelButtonTemplate" text="Klick">
<Size x="100" y="25"/>
<Anchors><Anchor point="CENTER"/></Anchors>
<Scripts>
<OnClick>print("Geklickt!")</OnClick>
</Scripts>
</Button>
Secure Templates & Combat Lockdown
Combat Lockdown prüfen
if InCombatLockdown() then
print("Im Kampf - geschützte Operationen blockiert")
return
end
mySecureButton:SetAttribute("spell", "Heilende Berührung")
SecureActionButtonTemplate
local button = CreateFrame("Button", "MeinSecureButton", UIParent,
"SecureActionButtonTemplate")
button:SetSize(50, 50)
button:SetPoint("CENTER")
-- AUSSERHALB des Kampfes konfigurieren!
button:SetAttribute("type", "spell")
button:SetAttribute("spell", "Heilende Berührung")
Aktionstypen
| Typ | Attribute | Beschreibung |
|-----|-----------|--------------|
| spell | spell | Zauber wirken |
| item | item | Item benutzen |
| macro | macrotext | Makro ausführen |
| target | unit | Einheit anvisieren |
Modifikator-Tasten
button:SetAttribute("type", "spell")
button:SetAttribute("spell", "Blitzheilung")
button:SetAttribute("shift-type", "spell")
button:SetAttribute("shift-spell", "Große Heilung")
button:SetAttribute("ctrl-type", "spell")
button:SetAttribute("ctrl-spell", "Erneuerung")
hooksecurefunc
-- Sicheres Hooking ohne Taint
hooksecurefunc("SecureFunction", function(...)
print("Funktion wurde aufgerufen mit:", ...)
end)
TBC Classic Besonderheiten
Zauberränge
local name, rank = GetSpellInfo(spellId)
print(name, rank) -- "Heilende Berührung", "Rang 11"
CastSpellByName("Heilende Berührung(Rang 7)")
Krafttypen
local powerType = UnitPowerType("player")
-- 0 = Mana
-- 1 = Wut
-- 2 = Fokus (Jäger-Begleiter)
-- 3 = Energie
Begleiter-Zufriedenheit (Jäger)
local happiness, damageModifier, loyaltyRate = GetPetHappiness()
-- 1=Unglücklich, 2=Zufrieden, 3=Glücklich
Schamanen-Totems
local haveTotem, totemName, startTime, duration = GetTotemInfo(slot)
-- slot: 1=Feuer, 2=Erde, 3=Wasser, 4=Luft
DestroyTotem(slot)
Kampflog
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:SetScript("OnEvent", function(self, event)
local timestamp, subevent, _, sourceGUID, sourceName, sourceFlags,
sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags,
arg12, arg13, arg14, arg15 = CombatLogGetCurrentEventInfo()
if subevent == "SPELL_DAMAGE" then
local spellId, spellName, spellSchool = arg12, arg13, arg14
local amount = arg15
print(sourceName, "trifft", destName, "für", amount)
end
end)
Ressourcen
Offizielle Dokumentation
| Ressource | URL | |-----------|-----| | Warcraft Wiki | warcraft.wiki.gg/wiki/World_of_Warcraft_API | | Wowpedia | wowpedia.fandom.com/wiki/World_of_Warcraft_API | | Blizzard Dev Portal | develop.battle.net |
Ace3 Framework
| Bibliothek | Zweck | |------------|-------| | AceAddon-3.0 | Addon-Lebenszyklus | | AceDB-3.0 | SavedVariables mit Profilen | | AceConfig-3.0 | Optionen-Konfiguration | | AceConsole-3.0 | Slash-Befehle | | AceEvent-3.0 | Event-Registrierung | | AceGUI-3.0 | GUI-Widgets |
Tutorials: wowace.com/projects/ace3/pages/getting-started
Entwicklungs-Addons
| Addon | Zweck | |-------|-------| | BugSack + BugGrabber | Fehler sammeln | | DevTool | Tabellen/Frames inspizieren | | WoWLua | Lua-Scripting im Spiel | | IdTip | Spell/Item-IDs in Tooltips |
Addon-Plattformen
| Plattform | URL | |-----------|-----| | CurseForge | curseforge.com/wow/addons | | WoWInterface | wowinterface.com | | GitHub | github.com |
Nützliche In-Game-Befehle
/reload -- UI neu laden
/dump ausdruck -- Lua auswerten
/etrace -- Event-Debugger
/fstack -- Frames unter Mauszeiger
/console taintLog 1 -- Taint-Logging
Dokumentation erstellt Januar 2025