# Playable AzerothAI Realm This profile turns the current prototype into a realm you can connect a **WoW 3.3.5a client** to. It uses: - the `mod-playerbots/azerothcore-wotlk` **Playerbot** branch - `mod-playerbots` - `mod-ale` - AzerothAI's ALE bridge - MySQL - AzerothAI's local dashboard/runtime - optional Ollama + `qwen3.5:4b` The server exposes only the standard WoW ports needed by the client: - TCP 3724 — authserver - TCP 8085 — worldserver SOAP runs on TCP 7878 but the playable profile binds it to **127.0.0.1 only** for the AzerothAI operator/GM channel. ## Recommended network For the mini PC, the cleanest private setup is: ```text Windows WoW PC ─────┐ │ LAN or Tailscale HP EliteDesk ───────┘ ├─ AzerothCore ├─ Playerbots ├─ ALE ├─ AzerothAI └─ Ollama ``` If Tailscale is installed, the bootstrap automatically prefers the machine's Tailscale IPv4 address. Otherwise it uses the first LAN IPv4 address it can detect. You can override it: ```bash REALM_ADDRESS=192.168.1.50 bash deploy/playable/bootstrap.sh ``` ## Bootstrap Run this from the AzerothAI checkout on the Linux host: ```bash bash deploy/playable/bootstrap.sh ``` The script: 1. builds AzerothAI and initializes its local D1/SQLite state 2. generates private bridge/operator tokens 3. starts AzerothAI on port 8787 4. clones the Playerbots AzerothCore fork 5. installs `mod-playerbots` and `mod-ale` 6. mounts `ale/azerothai_bridge.lua` into the real worldserver 7. builds AzerothCore 8. prepares client data and databases 9. starts authserver/worldserver 10. updates the realm address so another machine can connect The generated secrets are stored outside the repo at: ```text ~/azerothai-playable/runtime.env ``` with owner-only permissions. ## Create your player/GM account AzerothCore recommends account creation through the worldserver console rather than manually creating auth rows. ```bash cd ~/azerothai-playable/azerothcore docker attach ac-worldserver ``` Then: ```text account create YOURNAME YOURPASSWORD account set gmlevel YOURNAME 3 -1 ``` Detach from Docker without stopping worldserver: ```text Ctrl-P, then Ctrl-Q ``` Then save the same GM account for AzerothAI's local SOAP client: ```bash bash deploy/playable/set-gm-credentials.sh YOURNAME YOURPASSWORD ``` Restart AzerothAI by stopping/re-running the playable profile so the new local credentials are loaded. ## Connect the WoW client In the 3.3.5a client's: ```text Data/enUS/realmlist.wtf ``` set: ```text set realmlist ``` Then launch the client normally and log in with the account you created. The realm should appear as: ```text AzerothAI Lab ``` ## Dashboard From another machine on the same LAN/Tailscale network: ```text http://:8787 ``` The dashboard and WoW realm are separate surfaces: - WoW client: live game world - AzerothAI dashboard: population, identities, memories, operator tools, events, model settings ## AI brain The realm can run without Ollama; decisions remain deterministic. When Ollama is available: ```bash ollama pull qwen3.5:4b ``` Then choose **Ollama** in AzerothAI's Server & Models page. Routine Qwen decisions use non-thinking mode so the small host spends its generation budget on a fast structured action instead of hidden reasoning. ## Autonomous living world The playable profile now enables a real unattended Playerbot population by default. - native Playerbots log in and keep playing even when no human is connected - bots remain fully active while alone - periodic artificial rerandomization/teleporting is pushed out to a one-year horizon so normal movement, questing, combat and leveling remain the source of progression - ALE emits authoritative Playerbot snapshots with character GUID/account bindings - AzerothAI adopts observed Playerbots as persistent resident identities - the local autonomy worker periodically turns each resident's goals/personality/memories into high-level PlayerBotAI intentions - AzerothCore/Playerbots remains authoritative for movement, combat, spells, quest rules, loot and actual outcomes - Zaku is bound to a physical Undead Warlock Playerbot when a suitable body exists; his plot-armor rule stays runtime-only and is never exposed to his character context For an already-running realm, apply the living-world upgrade with: ```bash bash deploy/playable/enable-autonomous-world.sh ``` The default target is 10 simultaneously active Playerbots. Override it before running the helper, for example: ```bash AZEROTHAI_RANDOM_BOTS=20 bash deploy/playable/enable-autonomous-world.sh ``` The helper does not report success merely because configuration files changed. It waits for real Playerbot accounts, physically-online bot characters, authoritative ALE observations, and at least one adopted AzerothAI resident. ## Useful commands Check status: ```bash bash deploy/playable/status.sh ``` Stop the lab while preserving all data: ```bash bash deploy/playable/stop.sh ``` Restart later by running bootstrap again. Worldserver logs: ```bash cd ~/azerothai-playable/azerothcore docker compose logs -f ac-worldserver ``` AzerothAI log: ```bash tail -f ~/azerothai-playable/azerothai.log ``` Autonomous high-level decisions: ```bash tail -f ~/azerothai-playable/autonomy.log ``` If your existing lab was created by the PC-lab helper, the scripts automatically detect `~/azerothai-pc-lab` as well. ## Storage By default: ```text ~/azerothai-playable/ ├── azerothcore/ ├── client-data/ ├── etc/ ├── logs/ ├── runtime.env ├── azerothai.log └── azerothai.pid ``` The project checkout keeps AzerothAI's local D1 state in `.wrangler/state`. Do not delete these directories if you want the realm and character history to survive restarts. ## Class training and leveling `ale/azerothai_training.lua` checks each managed resident after a level change and rechecks every minute. It visits a nearby class trainer when the core reports eligible spells, then uses the normal trainer purchase transaction. Purchases require interaction distance and sufficient character gold; spells and money are never granted. Combat, recovery, player control, and mixed parties suspend visits. Stalled visits release paused work and retry later. The monitor reports pending spells, trainer, blocked reason, and verified purchases separately. This requires the native ALE methods installed by: ```bash python3 deploy/playable/patch-native-training.py /path/to/azerothcore ``` Rebuild and deploy worldserver before enabling the training Lua module. The patch also restores the native RPG training trigger and prevents sightseeing flights for residents below level 60. Normal travel flight routes remain available. `install-lifecycle.py` copies the Lua module with the other resident services. Without the native API, the monitor reports that training is unavailable. Training state and recoverable strategy leases live in `acore_auth.azerothai_training`, one row per resident. Existing trainer purchases made outside this workflow are not retroactively included in its purchase count. Flight guards and telemetry use `HasUnitState(0x00000100)` (`UNIT_STATE_IN_FLIGHT`). ALE's `IsTaxi()` tests the flight-master NPC flag and must not be used to detect a player riding a taxi. Model decisions also yield to an active native flight.