Skip to content

Latest commit

 

History

History
executable file
·
85 lines (72 loc) · 6.66 KB

File metadata and controls

executable file
·
85 lines (72 loc) · 6.66 KB

CooldownTracker - AI Agent Instructions

Welcome! This document outlines the standards, conventions, and preferences for developing the CooldownTracker World of Warcraft Addon. Please adhere to these guidelines when suggesting or writing code.

🎯 Project Purpose

CooldownTracker is a lightweight, manual tracking tool for Raid Leaders in World of Warcraft (Midnight 12.0+). It displays a customizable grid/column of major healer cooldowns. The raid leader manually clicks abilities to start and reset their timers. It does not automate tracking based on combat log events, keeping the addon fast, simple, and strictly within Blizzard's UI terms of service.

🏗️ Architecture & File Structure

The addon is split into modular components, sharing a single private namespace (CT).

  • CooldownTracker.toc: The manifest. Controls load order (critical).
  • Data.lua: Defines the base abilities (CT.COOLDOWNS), default durations, icons, and class colors.
  • UI.lua: Handles rendering the main tracker window, row layouts (grid vs vertical), and the per-frame OnUpdate timer loop.
  • Settings.lua: Implements the in-game options panel (Escape -> Options -> AddOns) using the modern Settings API. Handles SavedVariables overrides.
  • Core.lua: The bootstrap file. Handles ADDON_LOADED, slash commands (/cdt), and initializes the UI and Settings.
  • .github/workflows/ci.yml: Luacheck lint workflow — runs on push to main and all PRs.
  • .github/workflows/release.yml: Packaging and GitHub Release workflow — runs on v* tag push.
  • .github/pull_request_template.md: PR template with WoW-specific checklist.
  • .luacheckrc: Luacheck static analysis configuration.
  • .pkgmeta: BigWigs packager metadata for release packaging.

🔁 CI/CD

The project uses GitHub Actions for linting and release packaging.

Workflows

Two separate workflow files handle CI and releases:

.github/workflows/ci.yml — triggers on push to main and on all pull requests:

  • Runs luacheck on all Lua files via nebularg/actions-luacheck@v1.

.github/workflows/release.yml — triggers on v* tag push only:

  • Runs luacheck as a gate, then runs BigWigsMods/packager@v2 to package the addon and create a GitHub Release with the zip attached.
  • Uses permissions: contents: write so the built-in GITHUB_TOKEN can publish releases — no additional secrets required.

Luacheck (.luacheckrc)

  • std = "lua51" covers standard Lua globals.
  • WoW API globals (CreateFrame, GetTime, C_Timer, Settings, etc.) are declared in read_globals.
  • Addon-owned globals (CooldownTrackerDB, slash command vars) are declared in globals.
  • When adding new WoW API calls: if luacheck starts reporting an undefined global, add it to read_globals in .luacheckrc.

Packager (.pkgmeta)

  • Dev-only files (AGENTS.md, .github/, .luacheckrc, .gitignore) are listed under ignore so they are excluded from the release zip.
  • When adding new dev-only files (e.g. test scripts, editor config), add them to the ignore list in .pkgmeta.

Releasing

git tag -a v1.2.0 -m "Version 1.2.0"
git push origin v1.2.0

Also update ## Version: in CooldownTracker.toc to match the tag before tagging.

📜 Coding Standards & Conventions

  1. Private Namespace: Always use the addon's private namespace passed by the WoW client on load. Do not pollute the global environment.
    local AddonName, CT = ...
    -- CT is the shared table across all files
  2. SavedVariables: Use CooldownTrackerDB for persistence. Initialize it in ADDON_LOADED in Core.lua. Current keys:
    Key Type Default Purpose
    columns number 1 Grid column count (1–9)
    classCounts table {} Per-class player counts (1–5)
    customDurations table {} Per-spell duration overrides (seconds)
    disabledSpells table {} Set of spell IDs hidden from tracker
    playSoundOnReady boolean true Play alert sound on cooldown expiry
    frameLocked boolean false Lock window position (disable drag)
    point, relPoint, x, y mixed nil Saved window position
    spellOrder table {} Ordered array of spell id strings defining tracker display order; empty = default
  3. Slash Commands: Register slash commands via the SlashCmdList table. Handle arguments cleanly.
  4. No Third-Party Libraries: The addon intentionally does not use Ace3 or other framework libraries to remain lightweight. Rely on the standard WoW API.

⚠️ Critical WoW API Anti-Patterns (Taint Avoidance)

World of Warcraft has a strict "taint" system for UI frames. Violating these rules will cause the addon to break the user's UI during combat.

  1. Dynamic Frame Creation: Do NOT use CreateFrame() or SetParent() dynamically in response to user input (e.g., inside an OnTextChanged or OnClick handler).
    • Fix: Pre-allocate a pool of frames at ADDON_LOADED time. Show/Hide and reconfigure existing frames.
  2. Rebinding Secure Scripts: Do NOT call SetScript("OnClick", ...) on protected templates (like UIPanelButtonTemplate) at runtime after initial creation.
    • Fix: Set the script once during creation. Have the script read data dynamically from the frame itself (e.g., local cd = self:GetParent().cd).
  3. Settings API: The Settings.OpenToCategory() function is fully protected in The War Within/Midnight.
    • Fix: Do not attempt to programmatically open the Settings menu from slash commands. Instruct the user via chat text to open it manually.

🎨 UI & Layout Preferences

  • Grid vs Vertical: The UI supports both a wide-row vertical layout (columns = 1) and a compact square-card grid layout (columns 2-9). Use CT:LayoutRows() to reflow.
  • Clickable Rows: Each spell row is a Button frame (not a plain Frame). The entire row is the click target — there is no separate "Used"/"Reset" button. OnClick is set once at creation time and reads row.cd dynamically to avoid taint.
  • Font: Use Fonts\\FRIZQT__.TTF with an "OUTLINE" flag for clear, readable text in the tracker.
  • Backdrops: Use the BackdropTemplate mixin for frames requiring backgrounds/borders. Main frame backdrop alpha is 0.55 (translucent); title bar is 0.65.
  • Title Bar Controls: The title bar contains a close button (UIPanelCloseButton, 18px) and a lock toggle button (plain Button, 32px) anchored to its left. The lock button uses Interface\\BUTTONS\\LockButton-Locked-Up / LockButton-Unlocked-Up textures and toggles CooldownTrackerDB.frameLocked. Always guard OnDragStart with a frameLocked check to avoid a Lua error when the frame is not movable.