Files
ets-module-collection/AI_README.md

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

2. Critical Constraints

When writing code for this repository, you MUST adhere to the following constraints:

  1. 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).
  2. Lua Tuples:
    • Lua functions often return multiple values (tuples).
    • TypeScript handles this via TSTL specific patterns (e.g., const [val1, val2] = someLuaFunc()).
  3. Import Restrictions:
    • Imports can only be 1 level deep.
    • You cannot import a file that itself imports another file. Keep dependency chains flat.
  4. JavaScript Built-ins:
    • Do NOT use specialized JavaScript built-ins (e.g., Promise, async/await, complex Array methods not supported by TSTL).
    • Only use features supported and compiled by TSTL into Lua.
  5. Module Naming & Structure:
    • AIO Modules MUST follow this naming convention:
      • Server side: [module].server.ts
      • Client side: [module].client.ts
    • This naming is required for the build system to compile them correctly.

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 incObjectEntries and incParseInt patterns seen in examples.
  • UI Construction: Use the WoWAPI types 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");