Files
AzerothAI/docs/ALE_CONTROL_PLANE.md
T
Richard Clark 5f0fc86cf9
Core tests / core (push) Successful in 9m57s
Full verification / application (push) Failing after 5m16s
Full verification / local-brain (push) Failing after 6m15s
Realm simulation / simulated-live-world (push) Failing after 5m32s
WoW integration lab / real-worldserver (push) Canceled after 17m23s
Import verified AzerothAI snapshot from GitHub
Source branch: feature/ai-brain-router
Source commit: c2a09e0460465201a58aaab56c71424e9a96405e
2026-09-22 13:12:54 -04:00

7.1 KiB

ALE Full-Control Bridge

AzerothAI uses ALE (AzerothCore Lua Engine / mod-ale) as its privileged in-world control plane.

Official documentation: https://www.azerothcore.org/eluna/index.html

ALE is an AzerothCore-specific fork and is not guaranteed to be compatible with scripts written for the original Eluna engine.

Architecture

                           ┌─────────────────────────┐
                           │      AzerothAI          │
                           │ identity / world model  │
                           └───────────┬─────────────┘
                                       │
                         intents       │       operator control
                                       │
                   ┌───────────────────┴───────────────────┐
                   │                                       │
          SAFE GAME CONNECTOR                    ALE CONTROL PLANE
          normal AI decisions                    privileged operator lane
                   │                                       │
                   │                              authenticated queue
                   │                                       │
                   └───────────────────┬───────────────────┘
                                       │
                             ┌─────────▼─────────┐
                             │ AzerothCore + ALE │
                             │   worldserver     │
                             └───────────────────┘

A resident model never receives ALE credentials and cannot submit ALE commands.

Why ALE

The current ALE documentation exposes 30 game-side classes and seven Playerbots classes. It includes large surfaces such as Global, Player, Unit, Creature, GameObject, Map, WorldPacket and PlayerBotAI.

Examples relevant to AzerothAI include:

  • global timed events and event registration
  • world/server/player/map/weather/auction hooks
  • server command execution
  • world/character/auth database access
  • spawning creatures and GameObjects
  • player inventory, money, quests, reputation, skills, spells and teleportation
  • Unit health, movement, combat, auras, factions and emotes
  • chat and packet access
  • Playerbot strategy/action control
  • Playerbot inventory/quest/world-object observation

The full operator lane exists so AzerothAI does not need a new REST endpoint every time we want to use another documented ALE method.

Two-way transport

ALE has non-blocking HTTP requests, so the bridge is pull/push:

ALE -> AzerothAI

ale/azerothai_bridge.lua sends authoritative world events to:

POST /api/bridge/ale/event

Initial subscriptions include:

  • server startup/shutdown
  • weather
  • game-event start/stop
  • player login/logout
  • killed by creature
  • level changes
  • chat/whisper
  • zone/map changes
  • first login
  • combat enter/leave
  • repop/resurrect
  • achievement
  • quest acceptance

A player-zone event automatically feeds the World Population Director.

Additional ALE event hooks can be added locally or dynamically through the operator lane.

AzerothAI -> ALE

The ALE script polls:

GET /api/bridge/ale/poll

The server returns one authenticated Lua command chunk. The command executes inside ALE and reports completion to:

POST /api/bridge/ale/result

Commands and recent event telemetry are stored separately from the main realm-state JSON so frequent bridge polling does not fight with normal realm-state revisions.

Operator API

POST /api/ale/operator

Requires:

Authorization: Bearer <ALE_OPERATOR_TOKEN>

Supported request modes:

AzerothCore command

{"kind":"command","command":"server info"}

Compiles to ALE RunCommand.

Global ALE method

{"kind":"global","method":"SendWorldMessage","args":["The world is changing."]}

Player method

{"kind":"player","player":"Zaku","method":"GetHealth"}

Player inherits WorldObject and Unit methods, so this lane also covers inherited methods available to a Player.

PlayerBotAI method

{"kind":"playerbotAI","player":"Zaku","method":"DoSpecificAction","args":["follow"]}

Raw ALE Lua

{"kind":"raw","source":"return GetPlayerCount()"}

Raw execution is the escape hatch for the complete documented ALE surface: Creature, GameObject, Map, Group, Guild, Item, WorldPacket, specialized Playerbots managers, new ALE methods added later, custom event registration, and multi-step operations.

It is disabled unless:

ALE_RAW_EXEC_ENABLED=true

Raw mode is intended only for the private operator environment.

Security boundary

There are two separate credentials:

  • ALE_BRIDGE_TOKEN: known only by AzerothAI and the worldserver Lua bridge.
  • ALE_OPERATOR_TOKEN: protects the privileged operator API.

The LLM/provider code knows neither token and has no route that accepts an ALE command.

Raw Lua is intentionally not exposed through the ordinary /api/actions endpoint.

Installation

Build ALE in AzerothCore:

cd /path/to/azerothcore/modules
git clone https://github.com/azerothcore/mod-ale.git mod-ale

Re-run CMake and rebuild AzerothCore.

Copy:

ale/azerothai_bridge.lua

into the server's lua_scripts directory.

Add to the private worldserver configuration:

AzerothAI.Url = "http://127.0.0.1:3000"
AzerothAI.Token = "same-value-as-ALE_BRIDGE_TOKEN"
AzerothAI.PollMs = "750"
AzerothAI.ProtectedCharacter = "Zaku"

On AzerothAI configure:

ALE_BRIDGE_TOKEN=<strong random secret>
ALE_OPERATOR_TOKEN=<different strong random secret>
ALE_RAW_EXEC_ENABLED=true

Use raw execution only when AzerothAI is deployed privately and the operator endpoint is not exposed without authentication.

Zaku plot armor

The ALE bridge installs damage modifiers for common player- and creature-originated damage paths.

When the target name matches AzerothAI.ProtectedCharacter:

damage >= current health
        ↓
new damage = current health - 1
        ↓
Zaku remains at 1 HP

This rule lives only in runtime infrastructure.

Zaku's identity context, memories, and language-model prompt do not include the plot-armor setting.

AzerothAI still treats any bridge report claiming Zaku died as a control-plane fault rather than writing a death record.

What "full control" means

The bridge provides an operator path to everything exposed to Lua by the installed ALE build.

It does not magically expose private/internal C++ APIs that ALE itself does not bind. If we later need a core function that is not present in ALE, that specific function belongs in a small custom AzerothCore C++ module and can be attached to the same control plane.

This keeps our architecture layered:

  1. ALE first for documented live-world control.
  2. AzerothCore commands where appropriate.
  3. SQL only where a supported API is insufficient.
  4. Custom C++ bindings only for genuinely unexposed core behavior.