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

228 lines
7.1 KiB
Markdown

# 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
```text
┌─────────────────────────┐
│ 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
```json
{"kind":"command","command":"server info"}
```
Compiles to ALE `RunCommand`.
### Global ALE method
```json
{"kind":"global","method":"SendWorldMessage","args":["The world is changing."]}
```
### Player method
```json
{"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
```json
{"kind":"playerbotAI","player":"Zaku","method":"DoSpecificAction","args":["follow"]}
```
### Raw ALE Lua
```json
{"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:
```bash
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:
```ini
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:
```text
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`:
```text
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.