Files
CritTracker/AGENT_GUIDE.md
Sarah Kuhn bf81a9f75a Wechsel auf UNIT_COMBAT Engine (WoW Forever Beta Interface 16001)
- Entferne deaktiviertes COMBAT_LOG_EVENT_UNFILTERED
- Implementiere UNIT_COMBAT mit Anti-Triplet Filter (unit == 'target')
- Doppel-Auslösungs-Schutz bei Selbstheilung
- Mapping von school auf lokalisierte Schadensschulen (SCHOOL_NAMES)
- Parameter-Validierung mit issecretvalue
- AGENT_GUIDE.md aktualisiert
2026-09-30 10:09:23 +02:00

212 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CritTracker – Entwickler- & Agenten-Leitfaden (Developer & Agent Guide)
Dieses Dokument dient als technische Referenz für Entwickler und KI-Agenten, die das Addon **CritTracker** nachvollziehen, erweitern oder in einer vergleichbaren Umgebung reproduzieren möchten.
---
## 1. System- & Zielumgebung
- **Spiel / Client:** World of Warcraft - Forever (Beta)
- **Engine-Basis:** WoW Retail 12.x Engine
- **TOC Interface-Version:** `16001` (`## Interface: 16001`)
- **Addon-Verzeichnis:** `Interface/AddOns/CritTracker/`
- **Slash-Befehle:** `/ctr`, `/crittracker` (Hinweis: `/ct` wurde bewusst vermieden, um Namenskonflikte mit anderen Addons wie CTMod auszuschließen).
---
## 2. Projektstruktur
```
CritTracker/
├── CritTracker.toc # Addon-Manifest für Interface 16001
├── Localization.lua # Lokalisierungs-Strings (deDE und enUS)
├── CritTracker.lua # Core Engine: Event-Handling, Combat-Log, Cooldown, Reset
├── Config.lua # UI: 2-Spalten Einstellungsmenü (Modern Settings API + Standalone)
├── README.md # Benutzerdokumentation
├── AGENT_GUIDE.md # Diese technische Spezifikation für Agenten
└── sounds/
├── German/ # Deutsche Audio-Dateien
│ ├── crit1.mp3 .. crit4.mp3
│ ├── heal1.mp3 .. heal4.mp3
│ └── low.mp3
└── English/ # Englische Audio-Dateien
├── crit1.mp3 .. crit4.mp3
├── heal1.mp3 .. heal4.mp3
└── low.mp3
```
> [!IMPORTANT]
> **Audio-Asset-Korrektur:** Die ursprüngliche Datei `sounds/English/low.mp3` war eine fehlerhafte 1.024-Byte-Null-Datei (Stille). Sie wurde durch die funktionierende Audiodatei aus `sounds/German/low.mp3` ersetzt, damit englische Clients nicht stumm bleiben.
---
## 3. Datenarchitektur (`SavedVariables: CritTrackerDB`)
Die Daten werden in `CritTrackerDB` gespeichert. Die Konfiguration ist accountweit geteilt, während die Rekorde strikt pro Charakter und Realm isoliert sind.
```lua
CritTrackerDB = {
settings = {
enabled = true, -- Addon an/aus
enableChat = true, -- Lokale Chat-Ausgabe an/aus
enableSound = true, -- Soundausgabe an/aus
enableLowCrit = true, -- Erkennung schwacher Crits an/aus
lowThreshold = 30, -- Grenzwert in Prozent (Standard: 30%)
cooldown = 5, -- Cooldown in Sekunden (1-30s, Schieberegler)
damageSound = "crit1", -- "crit1", "crit2", "crit3", "crit4", "none"
healSound = "heal1", -- "heal1", "heal2", "heal3", "heal4", "none"
lowSound = "low", -- "low", "none"
soundChannel = "Master", -- "Master", "Dialog", "SFX"
language = "auto", -- "auto", "German", "English"
announceMode = "all", -- "all" oder "records_only"
},
chars = {
["CharakterName - RealmName"] = {
level = 80,
maxDamage = 152000,
maxDamageSpell = "Feuerball",
maxHeal = 89000,
maxHealSpell = "Lichtblitz",
}
}
}
```
---
---
## 4. Logik- & Entscheidungsfluss (Core Engine)
### 4.1. Warum `UNIT_COMBAT` statt `COMBAT_LOG_EVENT_UNFILTERED`? (Root Cause)
Im "WoW Forever"-Client (Interface 16001 / 12.x Engine) ist die sogenannte Addon-Apokalypse aktiv:
- `COMBAT_LOG_EVENT_UNFILTERED` wurde von Blizzard für Addons **vollständig deaktiviert** und feuert niemals.
- Kritische Treffer und Heilungen müssen zwingend über das Event `UNIT_COMBAT` abgefangen werden.
### 4.2. Filterregeln & Mehrfachauslösungs-Schutz
`UNIT_COMBAT` feuert mit den Argumenten `(unit, action, modifier, amount, school)`.
1. **Forever Secret Values Schutz:**
Parameter werden mit `issecretvalue(val)` geprüft. Handelt es sich um ein geschütztes Geheimnis oder `nil`, wird das Event verworfen.
2. **Krit-Filter:**
Nur Events mit `modifier == "CRITICAL"` und numerischem `amount > 0` werden akzeptiert.
3. **Schaden-Filter (Crucial Anti-Triplet):**
- Es wird ausschließlich `action == "WOUND"` und `unit == "target"` ausgewertet.
- Alle Pseudo-Einheiten wie `nameplate*`, `softenemy` etc. werden verworfen, da der Client denselben Treffer sonst 3-fach meldet.
4. **Heilung-Filter (Anti-Selfheal-Duplicate):**
- Akzeptiert `action == "HEAL"` für `unit == "target"` oder `unit == "player"`.
- Bei Selbstheilung mit sich selbst im Ziel (`UnitIsUnit("player", "target")`) wird die Auswertung auf `unit == "target"` beschränkt, um doppelte Auslösungen zu verhindern.
5. **Schadensschulen-Mapping (`SCHOOL_NAMES`):**
Da `UNIT_COMBAT` keine konkreten Zaubernamen liefert, wird das Argument `school` auf die jeweilige Schadensart gemappt:
- `0` / `1` = Physisch / Physical
- `2` = Heilig / Holy
- `4` = Feuer / Fire
- `8` = Natur / Nature
- `16` = Frost / Frost
- `32` = Schatten / Shadow
- `64` = Arkan / Arcane
### 4.3. Ablaufdiagramm der Crit-Verarbeitung
```mermaid
flowchart TD
A["Event: UNIT_COMBAT(unit, action, modifier, amount, school)"] --> B{"IsPublic? modifier == 'CRITICAL'?"}
B -- Nein --> End[Abbruch]
B -- Ja --> C{"action & unit Check"}
C -- "WOUND & unit == 'target'" --> D["isDamage = true"]
C -- "HEAL & (target oder player ohne Self-Duplicate)" --> E["isHeal = true"]
C -- Andere Units/Actions --> End
D --> F["Löse school via SCHOOL_NAMES auf"]
E --> F
F --> G["Hole bisherigen Rekord (charData.maxDamage / maxHeal)"]
G --> H{"amount > currentRecord?"}
H -- Ja --> I["Neuer Rekord! Aktualisiere charData (maxRecord = amount)"]
H -- Nein --> J{"enableLowCrit UND currentRecord > 0 UND amount <= threshold?"}
J -- Ja --> K["Als Low-Crit markieren (Sound: low.mp3)"]
J -- Nein --> L["Als normaler Crit markieren (Sound: critX / healX)"]
I --> M{"GetTime() - lastOutputTime < cooldown?"}
K --> M
L --> M
M -- Ja (im Cooldown) --> N["Ausgabe unterdrückt (Anti-Spam)"]
M -- Nein (Cooldown frei) --> O["lastOutputTime = GetTime()"]
O --> P["PlaySoundFile(soundPath, soundChannel)"]
O --> Q["DEFAULT_CHAT_FRAME:AddMessage(formatierte Nachricht)"]
```
---
## 5. Kernfunktionen im Detail
### 5.1. Level-Up Reset
- **Event:** `PLAYER_LEVEL_UP`
- **Sicherheits-Check:** Beim Login (`PLAYER_LOGIN`) wird geprüft, ob `UnitLevel("player") > charData.level`. Falls der Spieler offline oder bei deaktiviertem Addon aufgestiegen ist, wird der Reset nachträglich durchgeführt.
- **Wirkung:** `maxDamage = 0`, `maxHeal = 0`, `level = newLevel`.
- **Chat-Meldung:** Gibt lokalen Hinweis aus: `[CritTracker] Stufenaufstieg! Krit-Rekorde wurden auf 0 zurückgesetzt.`
### 5.2. Cooldown für Audio- & Chat-Ausgabe
- Einstellbar von **1 bis 30 Sekunden** über den Schieberegler in den Optionen.
- **Wichtig für Agenten:** Der Cooldown blockiert **nicht** das Speichern neuer Rekorde! Trifft ein Spieler während des Cooldowns einen neuen Rekordwert, wird `charData.maxDamage` sofort aktualisiert. Lediglich die Soundwiedergabe und der Textchat werden gedrosselt, um Tonaussetzer und Chatüberflutung zu verhindern.
### 5.3. Lokale Chat-Ausgabe
- Alle Chat-Meldungen verwenden `DEFAULT_CHAT_FRAME:AddMessage(msg)` oder `print(msg)`.
- Es werden **keine** öffentlichen Chatkanäle (`SAY`, `PARTY`, `RAID`) angesprochen. Die Ausgabe ist garantiert nur für den lokalen Client sichtbar.
- Abschaltbar über `CritTrackerDB.settings.enableChat`.
### 5.4. Zweisprachigkeit (Localization Architecture)
- Lokalisierungs-Proxy via Lua-Metatable in `CritTracker.L`:
```lua
CritTracker.L = setmetatable({}, {
__index = function(_, key)
local lang = CritTracker:GetActiveLanguage()
local locKey = (lang == "German") and "deDE" or "enUS"
return addonTable.Locales[locKey][key] or addonTable.Locales["enUS"][key] or key
end
})
```
- **Sprachauflösung:**
- `auto`: Prüft `GetLocale()`. Bei `deDE` wird Deutsch gewählt, bei allen anderen Sprachen Englisch.
- `German`: Erzwingt Deutsch.
- `English`: Erzwingt Englisch.
- **Audio-Pfad:**
`Interface\AddOns\CritTracker\sounds\<Language>\<SoundKey>.mp3`
---
## 6. UI-Architektur (`Config.lua`)
Das Einstellungsmenü ist für maximale Kompatibilität mit modernem Retail WoW (Dragonflight, War Within, Midnight / 12.x) ausgelegt:
1. **Modern Settings API:**
- Registrierung über `Settings.RegisterCanvasLayoutCategory(panel, "CritTracker")` und `Settings.RegisterAddOnCategory(category)`.
- Öffnen über `Settings.OpenToCategory(category:GetID())`.
2. **Standalone-Fallback:**
- Sollte das Settings-Menü im Betastatus nicht ansprechbar sein oder während des Kampfes aufgerufen werden, öffnet sich das Panel automatisch als bewegliches Standalone-Fenster (`BackdropTemplateMixin`, Close-Button, Dragging).
3. **2-Spalten-Layout:**
- **Linke Spalte:** Checkboxen (Addon, Chat, Sound, Low-Crit), Cooldown-Slider (1–30s), Schwellenwert-Slider (5–100%), Charakter-Rekordanzeige und Reset-Button.
- **Rechte Spalte:** Sound-Auswahl (Schaden, Heilung, Low, Kanal), Sprachauswahl und Test-Buttons (`►`).
---
## 7. Anleitung zur Nachbildung / Testen
1. **Dateien anlegen:** Die Dateien `CritTracker.toc`, `Localization.lua`, `CritTracker.lua` und `Config.lua` wie spezifiziert erstellen.
2. **Sounds ablegen:**
- `sounds/German/`: `crit1.mp3` bis `crit4.mp3`, `heal1.mp3` bis `heal4.mp3`, `low.mp3`.
- `sounds/English/`: `crit1.mp3` bis `crit4.mp3`, `heal1.mp3` bis `heal4.mp3`, `low.mp3`.
3. **Im Spiel testen:**
- `/ctr` eingeben -> Einstellungsfenster muss sich öffnen.
- Auf die `►`-Buttons klicken -> Die jeweiligen MP3-Dateien müssen hörbar abgespielt werden.
- `/ctr test crit` -> Testet Schadensmeldung und Audio.
- `/ctr test heal` -> Testet Heilungsmeldung und Audio.
- `/ctr test low` -> Testet Low-Crit-Meldung und `low.mp3`.
- Schieberegler verstellen -> Werte in `CritTrackerDB.settings` müssen persistieren.
- `/ctr reset` -> Rekorde werden auf 0 gesetzt.