# 无限工坊：用 AI 写魔兽插件

> 写给 AI Agent 的说明。用户把它交给你，是想请你帮忙装好无限工坊、接上它的 MCP 服务器，再用它编写和调试《魔兽世界：无限》的插件。网页版：<https://wuxianwow.com/workshop>

已经能调用 `wuxian` MCP 服务器的工具（例如 `status`）：先调用 `status`，`link.state` 是 `online` 就按下面的「开发循环」工作。还没有这些工具：先帮用户走完「安装」和「接入 Agent」。

## 无限工坊是什么

无限工坊（Wuxian Workshop）是 Windows 上的免费开源程序（MIT 许可）。它带一个 MCP 服务器 `wuxian`，把你连到用户电脑上正在运行的《魔兽世界：无限》客户端（国服 Beta）：你自己写插件，写完先检查，热加载进游戏里试，读报错（带调用栈）、print 输出、被拦截的操作和截图，对照这个客户端自己的 API 手册改好再试，改坏了能退回。新写插件、修改用户装着的插件（别人写的也行）都可以；用户只需说清想要什么，在游戏里验收。

- 程序：本机服务、MCP 服务器、桌面窗口（App）、安装与自检。
- 游戏里的开发组件：两个普通插件。`!WuxianWorkshop` 收集所有插件的 Lua 报错；`WoWBridge` 和程序通信、执行你送来的代码。
- 不读游戏内存、不注入代码、不模拟按键：开发组件在游戏窗口左上角画一小块色块（帧码），程序截取游戏窗口读出来；程序往插件目录里写字体文件，插件再读回来。重载界面只能由用户在游戏里点按钮。

## 系统要求

- 64 位 Windows 10（1809 或更新）或 Windows 11；游戏窗口被别的窗口挡住时也保持连接，需要 Windows 10 1903 或更新
- WebView2 运行时（Windows 11 自带，缺了程序会提示安装）
- 《魔兽世界：无限》客户端
- 一个支持 MCP 的 AI Agent（Claude Code、Codex、Cursor 等）

## 安装

标【用户】的步骤要用户自己在电脑上操作。是否装过：看 `%LOCALAPPDATA%\WuxianWorkshop.App\current\wuxian.exe` 在不在。

1. 下载：安装包和便携版在[网页的下载区](https://wuxianwow.com/workshop#download)。最新版本的版本号、更新说明、文件名、大小与 SHA-256 在 [latest.json](https://wuxianwow.com/workshop/releases/latest.json)：`setup.file`（安装包）或 `portable.file`（便携版 zip）接在 `https://wuxianwow.com/workshop/releases/` 后面就是下载地址；能运行命令的话，你可以替用户下载并核对 SHA-256。
2. 【用户】运行安装包：装在当前用户下，不需要管理员权限。安装包暂时没有代码签名，Windows 提示「已保护你的电脑」时点「更多信息」→「仍要运行」。装好后无限工坊自动打开。
3. 【用户】跟着 App 的「开始」页走完五步：找到游戏、装开发组件、进入游戏、接上 Agent、建第一个插件，每步做完自动打勾。
4. 【用户】装完开发组件要完整重启游戏：游戏只在启动时发现新插件，`/reload` 不够。进入游戏世界后，小地图边上的 ‹∞› 按钮提示「链路：在线」就成了。
5. 把无限工坊接到你这里（下一节），然后调用 `status`。

## 接入 Agent

App 的「开始」页或「接入 Agent」页能一键接入 Claude Code、Codex、Cursor（用户级设置，所有项目都能用），还会检查 Agent 能不能真的启动无限工坊。手动接入用 stdio：由 Agent 启动 `wuxian.exe mcp`，它会找到正在运行的无限工坊（没开就替用户打开）。下面的 `<wuxian.exe>` 换成安装位置的完整路径，通常是 `%LOCALAPPDATA%\WuxianWorkshop.App\current\wuxian.exe` 展开后的路径；运行 `"<wuxian.exe>" mcp-config claude`（或 `codex`、`cursor`）会打印填好本机路径的配置。

Claude Code：

```sh
claude mcp add --scope user wuxian -- "<wuxian.exe>" mcp
```

Codex：

```sh
codex mcp add wuxian -- "<wuxian.exe>" mcp
```

Cursor（项目里的 `.cursor/mcp.json`，或对所有项目生效的 `~/.cursor/mcp.json`；JSON 里路径的反斜杠写成 `\\`）：

```json
{
  "mcpServers": {
    "wuxian": { "command": "<wuxian.exe>", "args": ["mcp"] }
  }
}
```

接好以后，Agent 一般要新开会话或重连 MCP 服务器才看得到这些工具；无限工坊更新后也要重连一次（Claude Code：`/mcp`）。

## 工具（MCP 服务器 `wuxian`）

| 工具 | 用途 |
|---|---|
| `status` | 守护进程、游戏窗口与链路的状态：`link.state` 是 `online` 时 run / load 才能用；调用超时先看它 |
| `check` | 进游戏前检查插件或单个文件，几毫秒、不运行：Lua 5.1 语法、这个客户端没有的库和函数、拼错的名字、忘了 `local` 的全局变量、受保护函数、受限事件、.toc 与 XML；游戏在线时，手册查不定的名字直接问游戏 |
| `load` | 把一个 Lua 文件或整个插件（按 .toc 顺序）热加载进游戏，不用 /reload；先检查，有语法错误就一个文件也不送；加载前自动存一版 |
| `watch` | 文件一保存就热加载（start / stop / list），结果在 `logs` 里 |
| `try` | 在游戏里做一件事（`code` 一段 Lua，或 `slash` 一行斜杠命令），一次带回结果和之后几秒里的报错（带调用栈）、print、警告、被拦截的操作、事件，可加截图 |
| `run` | 在游戏里执行 Lua，取回返回值（表展开 3 层，每个值原样带回；一共最多 4000 字节，超过时 `cut` 写明截在哪个值、带回了多少字节、后面还有几个没送）；出错时带消息和调用栈 |
| `logs` | 日志：各插件的 Lua 报错（ERR）、print（OUT）、警告（WARN）、被拦截（BLOCKED）、RUN 结果等；`since` 接着上次读，`kinds` 按类型筛选 |
| `snap` | 游戏窗口截图，可以只截一块 |
| `inspect` | 描述框体：显隐、透明度、大小、屏幕上的矩形、锚点、层级、文字或材质、子框体；`mouse=true` 看鼠标下面的框体 |
| `trace` | 录一段时间里游戏触发的事件和参数（受限事件不注册）：该监听哪个事件、参数长什么样 |
| `reload` | 请求重载界面：游戏里出现按钮，用户点了才重载 |
| `new_addon` | 从模板新建插件：.toc（Interface 号、存档变量）、Lua（斜杠命令和热加载钩子；`window` 模板多一个可拖动的窗口）和写给 Agent 的 `AGENTS.md` |
| `addons` | 游戏里装着的插件：标题、版本、Interface 号是否和客户端一致、依赖、按需加载、是否被禁用、报错次数 |
| `errors` | `!WuxianWorkshop` 存下的 Lua 报错（截至上次退出或 /reload）：同一个报错归成一条，带次数和调用栈 |
| `history` | 插件存过的版本，和某一版与现在的差异 |
| `checkpoint` | 把插件现在的样子存一版，附一句说明 |
| `restore` | 把插件的文件退回某一版（先存一份现在的，所以退回也能撤销）；之后 `load` 或 `reload` 才在游戏里生效 |
| `api_search` | 搜这个客户端自己的 API 手册（内置，不用开游戏）：函数、事件、枚举与结构，带签名；每条标出插件能不能调用（`call`：`ok` 可调用、`limited` 有限制、`protected` 受保护，`why` 是依据），`call="usable"` 只列插件能用的；对象的方法写作 `Frame:Hide` |
| `api_get` | 手册里的一个条目：参数、返回值与类型、能否为空、原始文档字段 |
| `api_manual` | 手册的专题：运行时、标准库、taint、机密值、配额、.toc、受保护函数、安全模板、GameRule、无限专属 API 等 |
| `doctor` | 自检：游戏目录、开发组件是否装好且是当前版本、能否读取游戏窗口等，每项带修复办法 |
| `install` | 把开发组件（重新）装进游戏的 Interface/AddOns；新文件要完整重启游戏 |
| `say` | 在游戏聊天框显示一行字，用户看得到（只显示，不执行） |

## 开发循环

1. `status`：`link.state` 是 `online`（游戏在运行、开发组件连着）。
2. 新插件用 `new_addon`，先读它生成的 `AGENTS.md`。改用户装着的插件（尤其是别人写的）之前，先 `checkpoint` 存一份原样。
3. 改代码。新文件要写进 .toc；游戏只在启动时读 .toc，新文件要完整重启游戏才认（热加载不受这个限制）。
4. `check`：先改掉 `errors`，再逐条看 `warnings`。
5. `load` 热加载进游戏，或者 `watch` 让文件一保存就热加载。
6. `try` 把功能走一遍：`slash` 给一行斜杠命令，或 `code` 给一段 Lua（例如按钮的 `:Click()`、用假参数调用事件处理函数），`ok` 为真才算过。界面看 `snap` 和 `inspect`；不知道该监听哪个事件、参数长什么样，用 `trace` 录。重复 3–6。
7. 只有重载才生效的改动（.toc、存档变量写盘、XML、只在登录时运行的代码）：`reload`，请用户点游戏里的按钮。
8. 改坏了：`history` 看版本和差异，`restore` 退回，再 `load` 一次。
9. 用户问「游戏里能不能做到」：先查手册，再用 `run` 实测，不要只凭记忆。

## 热加载要点

- 文件开头登记命名空间：`local addonName, ns = ...` 和 `WoWBridgeNS[addonName] = ns`，热加载时文件拿到的是同一个 `ns`。
- 热加载会把文件再运行一遍：事件框体、钩子只建一次（放进 `ns` 复用，或先 `UnregisterAllEvents`）；`ns.OnUnload()` 在重跑前收拾旧东西（藏起旧窗口、取消计时器）并返回要保留的状态，`ns.OnReload(state)` 在重跑后接回来。
- `ADDON_LOADED`、`PLAYER_LOGIN` 在热加载时不会再触发：初始化写成函数，登录时和 `OnReload` 里都调用。
- `new_addon` 的模板已经写好这些。结构复杂的现有插件热加载可能不干净（例如重复注册事件），这时用 `reload`。

## 这个客户端的规矩

- 《魔兽世界：无限》1.60.1：插件写 `## Interface: 16001`，号不对游戏会把它当成过期插件不加载（`check` 会提醒，`new_addon` 自动写对）；界面代码是正式服 Mainline（12.x）。
- Lua 5.1：没有 `io`、`os`、`require`、`loadfile`、`utf8`、`table.unpack`，没有 `//`、`goto` 和位运算符；文件用 UTF-8。
- 受保护函数（施法、选目标、移动等）插件不能调用；战斗中不能改受保护的框体（动作条、单位框体）。违规会出 `ADDON_ACTION_BLOCKED` / `ADDON_ACTION_FORBIDDEN`，`logs` 里看得到。
- 机密值（secret values）：战斗、首领战、PvP 对局、聊天锁定时，部分 API 返回机密值，只能原样传回暴雪 API，不能比较、运算、拼接或存进表。
- 不要注册 `COMBAT_LOG_EVENT_UNFILTERED` 这类受限事件：客户端会拦截，并弹窗让用户禁用插件。
- 只有用户点击才能重载界面。
- 正式服的资料不一定适用这里：用之前先查手册（`api_search`、`api_get`、`api_manual`），拿不准就在游戏里实测，例如 `run` `return type(C_Foo.Bar)`。网页版 API 手册：<https://wuxianwow.com/api/>
- 觉得被拦截了、没反应，或者用户说游戏里有弹窗：先看 `logs`（`kinds` 填 `ERR,BLOCKED`），再 `snap` 看游戏画面，很多警告只以弹窗出现。
- 不要模拟按键、读游戏内存、注入代码，也别让用户这样做；只用插件 API。

## 游戏里的开发组件

- 小地图 ‹∞› 按钮：左键打开面板，右键打开「调试输出」窗口，按住可以拖动；窗口关着时有新报错，按钮上显示条数。
- `/wb log`（加 `errors`、`runs` 或 `output` 只看一类）：游戏里的「调试输出」窗口，按时间列出 Lua 报错（带调用栈）、警告、被拦截的操作、print 输出，以及你热加载的每个文件、运行的每段代码（成败、耗时、返回值）。用户想知道你在游戏里做了什么、报了什么错，可以请他打开它看。
- 你热加载时，游戏屏幕上方会出现一条提示（出错时是红的）；用户可以在面板「设置」里或用 `/wb set toasts off` 关掉，关掉后改在聊天框里说。
- `/wb`：面板（概览、设置、诊断）；`/wb link` 在聊天框显示连接状态；`/wb unlock`、`/wb lock`、`/wb reset` 调整色块的位置；`/wb on`、`/wb off` 打开或关掉连接。
- `/wxw report on`、`off`、`status`：是否把所有插件的 Lua 报错存下来给 App 看；`/wxw clear` 清空。
- 左上角的小色块（帧码）是开发组件和程序之间的通道，别让别的窗口挡住它。角色在载入画面或色块关掉时链路离线，回来后自动重连。

## 更新与卸载

- 新版本发布后 App 会提示，下载、重启即可。游戏里的开发组件跟着程序更新：游戏关着时自动装好，开着就等退出游戏后再装，装好后完整重启游戏。
- 卸载：Windows 设置 → 应用 → 无限工坊。设置和日志在 `%LOCALAPPDATA%\WuxianWorkshop`，卸载不会删除。

## 链接

- 网页：<https://wuxianwow.com/workshop>
- 这份说明（Markdown）：<https://wuxianwow.com/workshop.md>
- 最新版本：<https://wuxianwow.com/workshop/releases/latest.json>
- 源码（MIT）：<https://github.com/kk8o/wuxian-workshop>；仓库里的 `AGENTS.md` 是写给参与开发无限工坊本身的 Agent 的
- API 手册网页版：<https://wuxianwow.com/api/>，和 `api_search`、`api_get`、`api_manual` 查到的是同一份资料

无限工坊和无限图鉴（wuxianwow.com）是同一个站长做的玩家自制工具，非官方，与暴雪娱乐、网易无关。
