Skip to content

Latest commit

 

History

History
266 lines (206 loc) · 14 KB

File metadata and controls

266 lines (206 loc) · 14 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

AzerothAdmin is a World of Warcraft 3.3.5 (Wrath of the Lich King) addon for AzerothCore server administrators and Game Masters. It provides an in-game GUI for executing GM commands. Written entirely in Lua using the Ace3 addon framework.

Build & Release

There is no traditional build system. This is a pure Lua addon loaded directly by the WoW client.

  • Release packaging: Automated via .github/workflows/release.yml, triggered by pushing version tags (v*)
  • Release output: ZIP containing two addons: AzerothAdmin/ (main) and AzerothAdmin_Models/ (on-demand model data from _build/AzerothAdmin_Models/)
  • Installation: Extract ZIP to World of Warcraft/Interface/AddOns/
  • No tests: Testing is done manually in-game on a 3.3.5 client

Architecture

Load Order (defined in AzerothAdmin.toc)

  1. Libraries — Ace3 framework + FrameLib, Graph
  2. Locales — 12 languages (enUS is the default/fallback)
  3. Commands — Server command functions (Main, Tele, Char, Ticket, Misc, Server, NPC, GO)
  4. Data — DBC constants, teleport locations
  5. Core — Init.lua (button registration), AzerothAdmin.lua (main addon class), DropDownStyle
  6. Modules — Linkifier (chat link parsing)
  7. Frames — UI layout definitions, loaded last since they reference everything above

Key Files

  • Core/AzerothAdmin.lua — Main addon class (Ace3 addon), database defaults, event handlers, core logic (~3300 lines)
  • Core/Init.lua — Registers all button scripts and control handlers
  • Frames/Frames.lua — Orchestrates UI creation, calls all Frames_Section*.lua builders
  • Commands/*.lua — Each file corresponds to a tab and contains functions that send server commands via chat
  • Data/DBC.lua — Game database constants (items, spells, creatures)
  • Data/TeleportTable.lua — Predefined teleport location database

Core Patterns

  • Ace3 addon: Created via LibStub("AceAddon-3.0"):NewAddon("AzerothAdmin", "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
  • Two locale namespaces: AzerothAdmin (UI labels/tooltips) and AzerothAdmin-Strings (command strings/messages)
  • FrameLib: Custom library wrapping WoW's CreateFrame API for cleaner frame definitions
  • Database: AceDB-3.0 with char (per-character) and profile (account-wide) scopes. Saved as AzerothAdminDb / AzerothAdminDbPerChar
  • Models addon: Data/Models.lua was moved to a separate LoadOnDemand addon (_build/AzerothAdmin_Models/) to save ~5.6 MB of memory

UI Structure

The addon has 8 tabs, each with a matching Frames/Frames_Section*.lua (layout) and Commands/*.lua (logic): Main, Tele, Char, Ticket, Misc, Server, NPC, GO. There is also a Log tab (Frames only, no Commands file).

UI Grid Layout (Char Tab)

Buttons in Frames/Frames_Section*.lua are positioned using offX (column) and offY (row) offsets from TOPLEFT of ma_midframe. The Char tab uses this grid:

Column offX
ColOne 140
ColTwo 222
ColThree 303
ColFour 385
ColFive 467
ColSix 548
ColSeven 630
Row offY
RowOne -30
RowTwo -52
RowThree -74
RowFour -95
RowFive -117
RowSix -139
RowSeven -160
RowEight -182
RowNine -204

Standard button size is 80x20. Columns 1-3 overlap with the player model area (bottom-left). The parameter box and clear button sit at offY = -231.

Char Tab Button Map

Current button positions (Label = locale display text):

Position Col1 (140) Col2 (222) Col3 (303) Col4 (385) Col5 (467) Col6 (548) Col7 (630)
Row1 (-30) Kill Revive GPS Jail (A) Jail (H) UnJail Ban
Row2 (-52) Show GUID PLAYER Info Distance Appear G Create BanInfo
Row3 (-74) MaxSkill Repair CombatStop Recall G Invite BanList
Row4 (-95) Kick BindSight UnBindSight Summon G Rank UnBan
Row5 (-117) Cooldown Morph Demorph GroupSumn G UnInv
Row6 (-139) Rename Aura UnAura Mute Bank G Delete
Row7 (-160) Chng Faction Freeze UnFreeze UnMute Dismount
Row8 (-182) Chng Race Possess UnPossess Damage
Row9 (-204) Customize ShowArea HideArea Save

Top bar (offY -1 to -4): LearnLang dropdown + Learn button, Reset dropdown + Reset button, Modify dropdown + EditBox + Modify button, Ban type dropdown. Bottom bar (offY -231): Parameter label, EditBox (240x20), Clear button.

UI Grid Layouts (Other Tabs)

Most tabs use free-form positioning rather than a strict grid. Key patterns:

  • Main Tab: Left sidebar (offX 10-174) for GM toggles and display controls (On buttons 120px at offX 10, Off buttons 40px at offX 134). Sidebar runs from offY -10 to -230. Right columns (offX 333-660) for command buttons. Speed/Scale sliders at offX 205. Parameter area at offY -231 (label offX 180, editbox offX 264, Clear Params offX 508). No strict grid.
  • Tele Tab: Three-column scroll list layout (offX 5/220/420) with FauxScrollFrames. Action buttons at offX 660. Vertical chaining with offY -2 gaps.
  • Ticket Tab: Horizontal bottom button bar at offY -226 (offX 5-505 in 85px steps). Top area has scroll lists and detail panels.
  • Misc Tab: Left-aligned settings column (offX 6-160) with checkboxes, sliders, color swatches. Dropdowns at TOPRIGHT/BOTTOMRIGHT.
  • Server Tab: Left area with network graphs (offX 10, 170). Right sidebar buttons at TOPRIGHT. Bottom bar for announce/settings.
  • NPC Tab: Uses same grid system as Char tab (same column/row offsets). Has model viewer at BOTTOMLEFT, emote dropdowns at top. ColFive is 498, ColSix is 585, ColSeven is TOPRIGHT-5 (different from Char). See NPC Tab Button Map below.
  • GO Tab: Three zones — left controls (offX 5-105), center model (offX 182-262), right movement panel (offX 584-706). Free-form positioning throughout.

NPC Tab Button Map

Col1=140, Col2=222, Col3=303, Col4=385, Col5=498, Col6=585, Col7=TOPRIGHT-5. Same row offsets as Char tab.

Position Col1 (140) Col2 (222) Col3 (303) Col4 (385) Col5 (498) Col6 (585) Col7 (TR-5)
Row1 (-30) Kill Respawn NPC Info Way Show
Row2 (-52) Freeze Way All Del NPC Add NPC Unfreeze Way
Row3 (-74) Way Add Way Show On NPC Add ID Move Stack
Row4 (-95) Way End Add Way Show Off NPC Del Come To Me
Row5 (-117) Way M Add Way M Del NPC Move Unfreeze Rnd NPC Distance
Row6 (-139) Possess UnPossess NPC Go [dist box] NPC Clear
Row7 (-160) Morph Demorph NPC Say Get GUID [GUID box] Show GUID
Row8 (-182) Bindsight UnBindsight NPC Yell ID Down [NPC ID box] ID Up
Row9 (-204) Aura UnAura Display Down [Display box] Display Up

Top bar (offY -1 to -4): Emote dropdown 1 (offX 5) + Play button (offX 124), Emote dropdown 2 (offX 210) + Play button (offX 299). Bottom bar (offY -231/-232): Parameter label (offX 142), EditBox 240x20 (offX 226), Clear Params (offX 470).

Button Name-to-Label Mapping

Button frame names (e.g., ma_namegobutton) often do not match their visible UI labels (e.g., "Summon"). The source of truth for button labels is Locales/enUS/enUS.lua, where locale keys map to display text. When looking for a button by its visible label, search the locale file first, then trace the locale key back to the frame definition in Frames_Section*.lua.

Common non-obvious mappings:

  • ma_namegobutton = "Summon" (.summon command)
  • ma_gonamebutton = "Appear" (.appear command)
  • ma_groupgobutton = "GroupSumn" (.groupsummon command)
  • ma_charchnagefaction = "Chng Faction" (note: typo in key name is intentional/legacy)

Button Enable/Disable Logic

Some buttons (Kill, Kick, Revive, Save) are dynamically enabled/disabled in Core/AzerothAdmin.lua via the PLAYER_TARGET_CHANGED event based on target state (alive/dead, player/NPC, self/other).

Adding a New Command Button

Four steps:

  1. Add localized tooltip and button text in Locales/<locale>/<locale>.lua
  2. Write the command function in Commands/<section>.lua
  3. Register the button, function, text, and tooltip in Core/Init.lua
  4. Draw the button in Frames/Frames_Section<section>.lua

Conventions

  • Locale strings use two files per language: <locale>.lua (UI text) and strings_<locale>.lua (command strings). enUS is always the default fallback.
  • Backslash paths in the .toc file — WoW requires backslash separators in .toc load lists.
  • Interface version is 30300 (WoW 3.3.5). Do not change this.
  • Commands are sent to the server by writing to the chat frame (e.g., SendChatMessage(".gm on")).

EditBox Style

All EditBoxes should be created as bare CreateFrame("EditBox", ...) frames (no InputBoxTemplate) and styled with the following pattern:

do
  local eb = CreateFrame("EditBox", "my_editbox", parent)
  FrameLib:AddGroupFrame("groupname", eb)
  eb:SetSize(width, height)
  eb:SetPoint("ANCHOR", parent, "ANCHOR", offX, offY)
  eb:SetAutoFocus(false)
  eb:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
  eb:SetFontObject("ChatFontNormal")
  eb:SetTextInsets(4, 4, 2, 2)
  eb:SetBackdrop({
    bgFile   = "Interface\\ChatFrame\\ChatFrameBackground",
    edgeFile = "Interface\\Buttons\\WHITE8X8",
    edgeSize = 2,
    insets   = { left = 2, right = 2, top = 2, bottom = 2 }
  })
  eb:SetBackdropColor(0, 0, 0, 0.6)
  eb:SetBackdropBorderColor(0.35, 0.35, 0.35, 1)
end
  • Add eb:SetMaxLetters(n) only when a character limit is required.
  • Do not use inherits = "InputBoxTemplate" — it adds internal textures that conflict with SetBackdrop and cannot be cleanly overridden.
  • OnEscapePressed must always be set manually since bare EditBoxes do not inherit it.

CheckBox Style

All CheckBoxes using OptionsCheckButtonTemplate must have their built-in textures hidden and a custom background applied immediately after the FrameLib:BuildButton call:

FrameLib:BuildButton({
  type = "CheckButton",
  name = "my_checkbox",
  group = "mygroup",
  parent = ma_midframe,
  setpoint = { ... },
  text = Locale["my_label"],
  inherits = "OptionsCheckButtonTemplate"
})
do
  local cb = _G["my_checkbox"]
  cb:GetNormalTexture():SetAlpha(0)
  cb:GetHighlightTexture():SetAlpha(0)
  cb:GetPushedTexture():SetAlpha(0)
  local bg = cb:CreateTexture(nil, "BACKGROUND")
  bg:SetSize(18, 18)
  bg:SetPoint("CENTER", cb, "CENTER", 0, 0)
  bg:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
  bg:SetVertexColor(0.2, 0.2, 0.2, 0.8)
end
  • GetNormalTexture() — hides the box border at rest
  • GetHighlightTexture() — hides the hover glow
  • GetPushedTexture() — hides the border shown on click
  • The 18x18 background gives a dark gray backdrop contrasting against the addon's dark frame
  • Do not use _G["buttonNameHighlight"]OptionsCheckButtonTemplate does not create a named highlight child; use GetHighlightTexture() instead

Slider Style

All Sliders using OptionsSliderTemplate must have their backdrop removed and replaced with a custom 4px track line immediately after the FrameLib:BuildFrame call:

FrameLib:BuildFrame({
  type = "Slider",
  name = "my_slider",
  group = "mygroup",
  parent = ma_midframe,
  size = { width = 80 },
  setpoint = { ... },
  inherits = "OptionsSliderTemplate"
})
do
  local s = _G["my_slider"]
  s:SetBackdrop(nil)
  local line = s:CreateTexture(nil, "BACKGROUND")
  line:SetHeight(4)
  line:SetPoint("LEFT", s, "LEFT", 10, 0)
  line:SetPoint("RIGHT", s, "RIGHT", -10, 0)
  line:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
  line:SetVertexColor(0.35, 0.35, 0.35, 1)
end
  • SetBackdrop(nil) removes the default raised border/background — there is no named child texture for it
  • The 10px insets keep the line from extending past the thumb endpoints
  • The $parentThumb texture (the drag handle) is the only named child of OptionsSliderTemplate and is left untouched

Changelog Maintenance

Always update CHANGELOG.md before committing. Follow the existing format:

  • Use category prefixes: ADD, REMOVE, FIX, IMPROVE, REPLACE, REORGANIZE, CHANGE, MIGRATE, OPTIMIZE
  • Keep entries concise and user-facing — omit internal details like frame names, offX values, or file lists
  • Group related changes into a single entry with sub-bullets only when needed for clarity
  • Minor changes (typo fixes, internal cleanup) get a single line with no sub-bullets

A PreToolUse hook will block commits that don't include CHANGELOG.md changes.

AzerothCore Command References