6.4 KiB
AI Developer Guide for ETS Module Collection
This repository contains World of Warcraft server modules written in TypeScript, which are transpiled to Lua using TypeScriptToLua (TSTL). These modules utilize the Eluna engine and the AIO (All In One) library for client-server communication.
1. Core Technologies & Context
- Eluna Engine: The scripting engine used by the WoW server (AzerothCore). Documentation
- TypeScriptToLua (TSTL): Transpiles TypeScript code to Lua 5.2 compatible code.
- AIO: Handles communication between the server (Lua) and the client (Lua/XML).
- UI Assets:
- Interface files:
../3.3.5-interface-files - Textures:
../wow-ui-textures
- Interface files:
2. Critical Constraints
When writing code for this repository, you MUST adhere to the following constraints:
- TypeScript Limitations:
- Not all TypeScript features are available. The code is transpiled to Lua.
- Avoid complex TypeScript features that do not map cleanly to Lua (e.g., complex generics, certain decorators).
- Lua Tuples:
- Lua functions often return multiple values (tuples).
- TypeScript handles this via TSTL specific patterns (e.g.,
const [val1, val2] = someLuaFunc()).
- Import Restrictions:
- Imports can only be 1 level deep.
- You cannot import a file that itself imports another file. Keep dependency chains flat.
- JavaScript Built-ins:
- Do NOT use specialized JavaScript built-ins (e.g.,
Promise,async/await, complexArraymethods not supported by TSTL). - Only use features supported and compiled by TSTL into Lua.
- Do NOT use specialized JavaScript built-ins (e.g.,
- Module Naming & Structure:
- AIO Modules MUST follow this naming convention:
- Server side:
[module].server.ts - Client side:
[module].client.ts
- Server side:
- This naming is required for the build system to compile them correctly.
- AIO Modules MUST follow this naming convention:
3. Architecture & Patterns
AIO Modules (Client/Server)
AIO modules allow you to write both server-side logic and client-side UI logic in TypeScript.
Pattern:
- Shared Logic: Define interfaces and types in the server file or a shared file (if 1 level deep).
- Server Entry (
.server.ts):- Handles game events, database interactions, and sends data to the client.
- Uses
aio.Handle(player, 'ModuleName', 'FunctionName', ...args)to call client functions.
- Client Entry (
.client.ts):- Handles UI creation, event listeners, and sends data to the server.
- MUST include the
if(!aio.AddAddon())check to prevent execution on the server side during initialization. - Uses
aio.Handle('ModuleName', 'FunctionName', ...args)to call server functions.
Example Structure (botmgr)
Refer to modules/UI/botmgr for a complete example.
Server (botmgr.server.ts):
/** @ts-expect-error */
let aio: AIO = {}; // Polyfill for TS
import { BotUnit } from "./botUnit";
// Define handlers callable by client
const botMgrHandlers = aio.AddHandlers('BotMgr', {
"EquipTheItem": EquipTheItem,
"UnequipTheItem": UnequipTheItem
});
function EquipTheItem(player: Player, ...args) { ... }
Client (botmgr.client.ts):
/** @noSelfInFile **/
/** @ts-expect-error */
let aio: AIO = {};
// Check to ensure this runs only on client
if(!aio.AddAddon()) {
const botMgrHandlers = aio.AddHandlers('BotMgr', {});
// Client-side handlers callable by server
botMgrHandlers.UpdateBotData = (data: BotData) => {
// Update UI
}
// Call server
aio.Handle("BotMgr", "EquipTheItem", ...args);
}
4. Development Tips
- Global Polyfills: Some globals are polyfilled in the main entry. Be aware of
incObjectEntriesandincParseIntpatterns seen in examples. - UI Construction: Use the
WoWAPItypes for creating frames and textures. - Debugging: Use
print()for basic logging.
5. Common Utilities & Classes
The repository provides shared utilities in modules/classes/. Prefer using these over custom implementations.
Logger (modules/classes/logger.ts)
Wraps standard Eluna printing functions with log levels.
import { Logger } from "../../classes/logger";
const log = new Logger("MyModule");
log.info("Something happened");
log.error("Something went wrong");
UI Utils (modules/classes/ui-utils.ts)
Helper functions for common UI tasks.
colors(name): Returns WoW color codes (e.g.,colors('RED')).CreateItemButton(parent, name, itemId, ...): Creates a button with an item icon and tooltip.MakeDraggable(frame): Enables drag-to-move on a frame.EscapeCloseable(frame): Allows the frame to be closed with the Escape key.
6. Constants & ID Mappings
Centralized constants are located in modules/constants/idmaps.ts. Always import from here instead of hardcoding IDs.
- Equipment:
BotEquipSlot,BotSlotName - Stats:
BotStat,BotStatLabel - Player Info:
ClassesMapping,RacesMapping,TalentSpecs - Items:
ItemQuality,ItemStat,SocketBonus
7. Server-Side Patterns
Database Interaction
Use Eluna's global DB functions for character data.
// Query
const result = CharDBQuery(`SELECT * FROM custom_table WHERE guid = ${player.GetGUID()}`);
if (result) {
const value = result.GetUInt32(0);
}
// Execute
CharDBExecute(`INSERT INTO custom_table (guid, value) VALUES (${player.GetGUID()}, 1)`);
State Management
For modules requiring state (like mythicplus), use a Map keyed by player GUID or Entry ID.
const StateStorage: Map<number, MyState> = new Map();
// Accessing state
const state = StateStorage.get(player.GetGUIDLow());
Event Handling
Register events using global Eluna functions.
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => MyCommandHandler(...args));
RegisterGameObjectEvent(ENTRY_ID, GameObjectEvents.GAMEOBJECT_EVENT_ON_USE, (...args) => OnUse(...args));
8. Client-Side Patterns
Frame Creation
Use standard WoW API (via WoWAPI types) to create frames.
const frame = CreateFrame("Frame", "MyFrame", UIParent, "UIPanelDialogTemplate");
frame.SetSize(300, 300);
frame.SetPoint("CENTER");
Sound
Use PlaySoundFile or PlaySound for audio feedback.
PlaySound("igCharacterInfoOpen");
PlaySoundFile("Sound\\Interface\\LootCoinLarge.wav", "Master");