如果你也曾经在《Minecraft》里花掉两小时重复挖矿、搬运箱子、往返跑图,你会理解为什么很多玩家想给游戏装一个"自动档"。而 MinecraftBot 的常见目标是让一个程序以独立玩家身份进入游戏,自动完成聊天、挖掘、战斗、寻路这些操作。我想给出的核心判断是:真正值得做的 MinecraftBot,不是按键精灵式的模拟鼠标键盘,而是一个基于 Minecraft 协议、用代码驱动的最小游戏客户端。 以 Node.js 生态中的 mineflayer 库为切入点,你可以在不修改游戏文件的情况下,用一个脚本完整实现"上线—感知—决策—行动"的自动循环。本文会从原理讲起,然后逐步写出一个能自动上线、响应聊天、挖矿、战斗、寻路并断线重连的机器人,同时把常见坑和工程建议一并整理清楚。
1. MinecraftBot 到底是什么:三条技术路线对比
很多新手第一次接触"游戏机器人"时,第一反应是模拟点击、录制鼠标宏,或者直接改内存。这三个方向在Minecraft里都存在,但它们的定位完全不同。在动手之前,先搞清楚路线,才能避免做完一个几天后就跑不起来的玩具。
| 路线 | 实现原理 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|---|
| 图形界面自动化 | 用 AutoIt、按键精灵等工具模拟鼠标键盘操作游戏窗口 | 实现简单,不依赖游戏协议细节 | 依赖窗口焦点、屏幕分辨率、帧率;游戏一卡就漂移;无法脱离画面运行 | 个人本地简单重复操作 |
| Mod / 注入 | 修改或扩展游戏客户端,把代码逻辑注入到游戏进程内 | 可以直接读取世界数据和玩家状态,功能非常强 | 与特定版本深度耦合,开发成本高,容易被反作弊机制识别 | 熟悉 Java / 字节码的进阶玩家 |
| 协议级机器人 | 独立实现一个网络客户端,不渲染画面,直接连接服务器收发游戏数据包 | 后台运行、跨平台、可多开,协议知识可以复用到其他网络项目 | 需要理解协议和事件驱动模型;部分高级功能要自己实现 | 想学习网络协议与自动化开发的工程师 |
我的判断很明确:如果目标是做一份长期有价值的"制作记录",第三路线的性价比最高。协议级机器人本质上就是一个最小化的游戏客户端,它不读内存、不开外挂、不替玩家点击屏幕,而是用程序对服务器说"我是一个独立玩家,请让我登录"。这种方式适合学习网络协议、事件驱动编程和自动化任务编排,也更容易在服务器上稳定运行。缺点是入门时有几个概念需要理解,但本文会用最小示例帮你跨过这个门槛。
需要强调一点:无论选择哪条路线,都必须遵守目标服务器的规则与服务条款。 在自建测试服务器中研究自动化是合理的学习行为,但在公共服务器上使用机器人挂机刷矿、干扰其他玩家,通常会被踢出甚至封号。后面所有示例都建议在你有管理权限的本地测试服务器中运行。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心原理:协议客户端与感知-决策-执行
Minecraft Java 版客户端和服务器之间的通信不是黑魔法,而是基于 TCP 连接的结构化数据包。玩家移动、方块更新、聊天消息、实体生成,本质上都对应着特定格式的数据包。mineflayer 之所以能做出 Bot,是因为它基于 node-minecraft-protocol 实现了这些协议的收发,并把底层封包翻译成了事件回调和方法调用。
你可以这样理解一个协议级 Bot 的运转方式。真实玩家靠眼睛看屏幕获取信息,Bot 没有画面,它靠事件流"感知"世界变化;真实玩家靠大脑决定下一步做什么,Bot 靠 if/else、状态机或任务队列来做决策;真实玩家靠键盘鼠标执行动作,Bot 靠调用 bot.chat()、bot.dig()、bot.attack()、bot.pathfinder.setGoal() 等方法把动作转化为数据包发给服务器。因此,一个 Bot 的核心循环可以抽象为四步:
- 感知:通过事件回调收集信息,例如收到聊天消息、看到实体生成、发现方块更新。
- 决策:根据当前目标和状态,决定下一步执行什么动作。
- 执行:调用 API 发送动作数据包,并等待服务器反馈。
- 等待:继续监听新事件,形成持续循环。
这个模型和写一个 IM 机器人、一个自动化测试框架、一个 RPA 脚本非常相似。所以我说,MinecraftBot 的第一个学习价值不是"游戏外挂",而是一个能让你亲自验证协议交互的自动化平台。
很多新手真正遇到的第一个坑,是"Bot 不动"。原因往往不是 API 不会用,而是事件时机没掌握好。因为没有画面,你必须等 spawn 事件触发后再执行动作;因为服务器世界是分区块加载的,findBlock 搜索方块时可能区块还没加载完;因为 bot.entity 在 spawn 之前可能是空的,直接读位置就会报错。所以实战项目里,我强烈建议先加日志确认事件顺序,再添加行为逻辑。事件驱动编程里另一个经典问题是回调执行次数不受控制:一次聊天消息如果被分发到多个地方,可能触发一百次挖矿动作。解决办法是加状态锁和节流,这一点在第 4 章和第 8 章会具体展开。
3. 环境准备与第一个能上线的机器人
3.1 环境清单
开发一个 MinecraftBot 的环境要求并不高,普通开发机都可以胜任:
- 操作系统:Windows、macOS、Linux 均可。
- Node.js:建议选择官方 LTS 版本,具体最低版本要求以 mineflayer 官方文档为准。
- 包管理器:npm,Node.js 安装后会自带。
- Minecraft Java 版服务器:最好在本机启动一个测试服务器,或者在你有权限、明确允许 Bot 的服务器上进行开发。
- 编辑器:VSCode 或任意熟悉的代码编辑器。
这里要专门说明一下版本意识。Minecraft 的 Java 版协议会在不同版本之间变化,mineflayer 的协议支持也会持续更新。本文给出的代码是通用写法,不绑定某个具体 Minecraft 版本。实际开发时,请以你安装的 mineflayer 和服务器版本为依据查阅官方文档,不要盲目把文章里的代码往生产环境里套。
3.2 初始化项目与安装依赖
先创建项目目录并初始化:
bash复制mkdir mc-bot
cd mc-bot
npm init -y
npm install mineflayer
安装完成后,可以用下面命令确认依赖已经存在:
bash复制npm list mineflayer
如果输出了 mineflayer@版本号,说明安装成功。接下来可以从最简单的连接脚本开始验证整个链条是否通畅。
3.3 第一个连接脚本
新建文件 bot.js,写入下面代码:
javascript复制// 文件路径:mc-bot/bot.js
const mineflayer = require('mineflayer')
const bot = mineflayer.createBot({
host: '127.0.0.1',
port: 25565,
username: 'BotPlayer01',
auth: 'offline'
})
bot.on('login', () => {
console.log('登录成功')
})
bot.on('spawn', () => {
console.log('已进入游戏世界')
bot.chat('大家好,我是自动化测试机器人')
})
bot.on('kicked', (reason) => {
console.log('被踢出服务器:', reason)
})
bot.on('error', (err) => {
console.error('连接出错:', err.message || err)
})
这段代码的意图很直接:createBot 负责初始化一个独立客户端;host 和 port 指向服务器地址;username 是在服务器中显示的玩家名;auth 指定认证方式。如果你的测试服务器是离线模式,用 offline;如果目标服务器是正版模式,需要按官方文档配置微软账号登录,通常会使用 auth: 'microsoft',这个过程涉及浏览器授权,不在本文详述。
运行方式也很简单:
bash复制node bot.js
如果一切正常,你应该在终端看到 登录成功 和 已进入游戏世界 两行日志,同时游戏服务器中会出现一个名为 BotPlayer01 的玩家,并在聊天栏看到机器人发送的问候。如果启动失败,最常见的错误是 ECONNREFUSED,意思是服务器地址或端口不通;另一个常见错误是登录失败,通常和 auth 配置不匹配有关。先解决这两个问题,再继续后面的功能开发。
4. 核心能力实战:聊天指令、自动挖矿、自动战斗
这一章是整篇文章的核心操作区。我们会把最常用的三个能力写进同一个机器人:响应聊天指令、自动查找并挖掘方块、自动攻击敌对实体。这三个能力刚好覆盖了"感知—决策—执行"的三种典型形态。
4.1 让机器人听懂聊天指令:事件驱动的第一个入口
在 bot.js 中追加一个 chat 事件监听。chat 事件会给出两个关键参数:发言玩家名 username 和消息内容 message。你要做的第一件事是过滤掉机器人自己的消息,否则机器人看到自己说"向前移动"也会触发一次动作,形成自循环。
javascript复制// 文件路径:mc-bot/bot.js
bot.on('chat', (username, message) => {
if (username === bot.username) {
return
}
if (message === '!pos') {
const pos = bot.entity.position
bot.chat(`我当前的坐标:${Math.floor(pos.x)}, ${Math.floor(pos.y)}, ${Math.floor(pos.z)}`)
}
if (message === '!forward') {
bot.setControlState('forward', true)
setTimeout(() => {
bot.setControlState('forward', false)
}, 3000)
}
})
先解释 !pos。当玩家在游戏里输入 !pos 时,Bot 会读取 bot.entity.position 并汇报自己的坐标。这里有一个关键点:bot.entity 在 spawn 事件之前不一定可靠,所以这段代码如果放在 spawn 之前执行,可能读到 undefined。在自己测试时,可以先等 Bot 生成后再执行。
再解释 !forward。setControlState('forward', true) 表示按住前进键,setControlState('forward', false) 表示松开前进键。Bot 不会自己停,所以你在开启移动后必须有一个定时器或状态判断把它关掉。更稳健的做法是引入状态字段,而不是裸用 setTimeout,因为定时器一旦和后续动作重叠,行为会非常混乱。
注意聊天指令的设计。多人服务器中的聊天内容很复杂,可能带有颜色代码、玩家前缀、插件格式,所以 message === '!pos' 这样的精确匹配在干净环境中够用,在复杂服中不一定成立。建议给机器人设计一个统一前缀,例如 !bot,然后解析后面的参数,或者直接把原始 chat 消息打印到控制台观察格式。
4.2 自动挖矿:世界感知与动作流程
自动挖矿看似简单,实际上是一个完整的感知-决策-执行流程:先找到目标方块,再调整视角,最后执行挖掘。这里用到两个关键 API:bot.findBlock 负责搜索方块,bot.dig 负责挖掘。
javascript复制// 文件路径:mc-bot/bot.js
bot.on('chat', async (username, message) => {
if (username === bot.username) {
return
}
if (message === '!mine') {
const target = bot.findBlock({
matching: (block) => block && block.name.includes('ore'),
maxDistance: 32
})
if (!target) {
bot.chat('附近没有找到矿石')
return
}
bot.chat(`找到 ${target.name},开始挖掘`)
await bot.lookAt(target.position)
await new Promise((resolve, reject) => {
bot.dig(target, (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
bot.chat('挖掘完成')
}
})
这段代码有三个容易踩坑的地方。第一个是 matching 函数。mineflayer 的 findBlock 会遍历当前已加载区块中的方块,matching 可以写方块 ID,但不同版本方块 ID 不一定稳定,所以我优先推荐写函数,用 block.name.includes('ore') 匹配所有名字里带 ore 的矿石方块。第二个是 maxDistance。搜索半径太大会导致 CPU 压力增大,太小则找不到目标,32 对我来说是一个比较合适的起点。第三个是挖掘前必须 lookAt(target.position)。如果机器人的视角朝向不对,dig 可能因为目标不在准星方向而失败。
还需要说明一个现实问题:机器人挖掘时,如果脚下的方块被挖掉,它可能会掉落;如果目标方块在上方三格以上,机器人也可能够不着。mineflayer 提供了一些底层能力,但真正要做一个稳定的自动挖矿机器人,你还需要处理移动、跳跃和路径规划,这会自然进入到第 5 章的寻路话题。
4.3 自动攻击敌对实体:用状态锁避免重复动作
自动攻击的逻辑比挖矿更强调频率控制。如果你在每个事件里都调用 attack,机器人会不停地挥动武器,既浪费资源又容易被服务器判定为破坏行为。这里使用 physicsTick 事件和自定义状态字段,保证每次攻击之间有一个冷却窗口。
javascript复制// 文件路径:mc-bot/bot.js
bot.status = 'idle'
bot.on('physicsTick', () => {
if (bot.status === 'fighting') {
return
}
const enemy = bot.nearestEntity((entity) => {
return entity && entity.type === 'hostile'
&& entity.position.distanceTo(bot.entity.position) < 8
})
if (enemy) {
bot.status = 'fighting'
bot.chat(`发现敌对实体,尝试攻击`)
bot.attack(enemy)
setTimeout(() => {
bot.status = 'idle'
}, 2000)
}
})
physicsTick 是每秒触发多次的高频事件,所以回调里绝对不要做阻塞式操作,所有重逻辑都不能直接挂在里面。bot.nearestEntity 会返回距离最近的符合条件实体,我这里用 type === 'hostile' 过滤出怪物,并限制距离在 8 格以内。找到目标后,把 bot.status 改成 fighting,执行一次 attack,等 2 秒后再恢复 idle,避免在同一个 tick 周期里反复攻击同一个目标。
这样做的本质是给 Bot 引入一个极简状态机:idle 代表空闲,fighting 代表战斗中。状态机思想会反复出现在自动化机器人项目中,因为游戏行为本身是"状态切换"的,一个机器人有多个动作时,裸用 if/else 很快就会失控。
5. 自动寻路:用 pathfinder 让机器人从 A 到达 B
自动挖矿和自动攻击解决了"单个动作",但真实任务几乎都要求机器人先从一个点移动到另一个点。比如玩家说"去坐标 100, 64, 200 挖矿",机器人得先走过去。这一步单独用 setControlState 做会很痛苦,因为你要自己处理跳跃、绕障碍、防止死胡同。更合适的做法是使用官方生态中的寻路插件 mineflayer-pathfinder。
先安装依赖:
bash复制npm install mineflayer-pathfinder
然后在脚本中引入插件并初始化移动能力:
javascript复制// 文件路径:mc-bot/bot.js
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder')
bot.loadPlugin(pathfinder)
bot.on('spawn', () => {
const mcData = require('minecraft-data')(bot.version)
const movements = new Movements(bot, mcData)
bot.pathfinder.setMovements(movements)
})
bot.on('chat', (username, message) => {
if (username === bot.username) {
return
}
if (message.startsWith('!go ')) {
const parts = message.split(' ').slice(1).map(Number)
if (parts.length === 3 && parts.every((v) => Number.isFinite(v))) {
const [x, y, z] = parts
const goal = new goals.GoalNear(x, y, z, 1)
bot.pathfinder.setGoal(goal)
bot.chat(`开始前往 ${x}, ${y}, ${z}`)
}
}
})
这里最关键的是 Movements 和 setMovements。Movements 定义了机器人的移动能力,包括哪些方块可以走、最大可跳过高度、是否游泳等。很多新手直接 loadPlugin(pathfinder) 后就开始设置目标,结果机器人一条消息都不回,或者站在原地不动,原因就是没有设置 movements。由于 bot.version 要等 bot 创建后才有值,所以把 Movements 的初始化放在 spawn 回调里是最稳妥的。
goals.GoalNear(x, y, z, 1) 表示把目标点设置到坐标附近 1 格以内,比较符合"到达某个区域"的需求。如果你希望机器人精确站到某个方块上,可以使用 GoalBlock。寻路期间,可以通过 bot.pathfinder.isMoving() 判断是否在移动中,也可以在 goalReached 事件里确认是否到达。
寻路是协议级机器人中最复杂的部分之一,但 mineflayer-pathfinder 帮你把 A* 风格的搜索封装好了。实际使用中,路径规划失败的可能原因包括:目标点在水下但机器人不会游泳、目标点在封闭空间、movements 未配置。这些都是可以通过日志判断的问题,不要把锅甩给"库不好用"。
6. 断线重连与任务稳定性
一个能跑一次的上线脚本并不难写,难的是一个机器人能长期稳定运行。在真实项目中,服务器可能重启、网络可能抖动、Bot 可能因为聊天气泡过多被插件误杀、甚至因为长时间无操作被踢下线。如果不做断线重连,你这台"自动化引擎"就是一次性的。
下面这段代码演示一个最小可用的重连模式。为了更清晰,我把创建 Bot 的逻辑封装成 createBot 函数,用三个事件控制生命周期:spawn 表示进入世界,end 表示连接结束,error 表示连接错误。
javascript复制// 文件路径:mc-bot/bot.js
let bot = null
let reconnectTimer = null
let reconnectDelay = 3000
function createBot() {
bot = mineflayer.createBot({
host: '127.0.0.1',
port: 25565,
username: 'BotPlayer01',
auth: 'offline'
})
bot.on('spawn', () => {
console.log('已进入游戏世界')
reconnectDelay = 3000
})
bot.on('kicked', (reason) => {
console.log('被踢出服务器:', reason)
})
bot.on('error', (err) => {
console.error('连接出错:', err.message || err)
})
bot.on('end', () => {
console.log(`连接结束,${reconnectDelay / 1000} 秒后重连`)
reconnectTimer = setTimeout(() => {
createBot()
}, reconnectDelay)
reconnectDelay = Math.min(reconnectDelay * 2, 60000)
})
}
createBot()
这段代码里我加入了一个简单的指数退避逻辑:第一次重连等 3 秒,如果仍然失败,等待时间翻倍,最大 60 秒。为什么不用固定时间?因为如果服务器正在重启,频繁重连会反复刷错误日志,还会给服务器造成不必要的连接压力。指数退避是网络服务中常见且稳健的策略。
需要特别注意一点:每次 createBot() 创建的都是一个全新 Bot 实例。如果你在第 5 章中给 Bot 加载了 pathfinder 插件,那么重连后的新实例也必须重新 loadPlugin、重新 setMovements。如果你把插件加载和 movements 配置放在 createBot 内部或 spawn 事件中,而不是只放在脚本初始化阶段,就不会出现"第一次正常,重连后失效"的诡异问题。另外,重连后要清理上一轮遗留的定时器和任务队列,否则可能出现两个 Bot 同时操作同一个账户的冲突。
7. 常见问题与排查思路
协议级机器人出错时,报错信息往往不会告诉我们"是哪一步逻辑错了",所以排查的思路比记忆答案更重要。下面这张表汇总了我在这个主题下最常见的问题,基本覆盖从启动到运行再到寻路的过程。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
启动报 Cannot find module 'mineflayer' |
依赖未安装或安装目录错误 | 检查 node_modules 是否存在,运行 npm list mineflayer |
重新执行 npm install |
连接报 ECONNREFUSED |
服务器地址或端口错误,服务器未启动 | 确认服务器配置 server.properties 中的端口,尝试用 Telnet 连接 |
修正 host / port,或先启动服务器 |
| 登录失败 | auth 配置与服务器认证模式不匹配 |
查看服务器是否开启正版验证 | 离线服使用 auth: 'offline',正版服按官方文档配置微软登录 |
| 被踢出服务器 | 协议版本不兼容、反作弊插件拦截、服务器禁止 Bot | 在 kicked 事件里打印 reason |
换到自建测试服开发,或锁定适配的 mineflayer 版本 |
| 机器人不动 | pathfinder 未加载、movements 未配置、目标不可达 | 确认 loadPlugin 已执行,检查 spawn 回调中是否 setMovements |
补上 movements 初始化;观察寻路失败日志 |
| 找不到方块 | 区块未加载、matching 函数写错、搜索距离太小 |
打印 findBlock 返回结果,先让 Bot 靠近目标区域 |
扩大 maxDistance,或先寻路到目标附近再搜索 |
| 聊天指令无响应 | 事件未触发、消息格式被插件改掉、机器人把自己的消息也算进去了 | 在 chat 事件里打印原始 username 和 message |
使用统一前缀并过滤机器人自己的消息 |
| 动作重复执行 | 高频事件中未加状态锁 | 检查 physicsTick 回调中是否有轻量逻辑 |
用状态字段和冷却时间约束动作 |
| 运行几小时后自动停止 | 服务器重启、网络断开、被踢 | 检查 end / kicked 日志 |
实现断线重连和指数退避 |
如果问题不知道从哪入手,我的建议是先看事件顺序。在 login、spawn、error、kicked、end 这几个事件里各加一行 console.log,输出时间戳和事件名。很多时候,问题并不是 API 用错了,而是事件根本没有按你预想的顺序发生。比如你调用 bot.chat 太早,机器人还没完全进入世界,自然发不出去;又比如你在 spawn 事件外读取 bot.entity.position,读到空对象,于是后面的动作全部失败。
8. 最佳实践与安全边界
这是很多教程不会专门讲,但实际项目中最容易踩雷的部分。一个能跑的 Bot 和一个能安全、稳定、长期跑的 Bot,差别往往不在 API,而在工程约束。
8.1 安全与合规边界
写 MinecraftBot 本质上是在写一个自动连接服务器的程序,所以底线问题必须先立住:
- 只在自建服务器、你有管理权限的服务器、或明确允许 Bot 的服务器上运行。
- 遵守服务器规则和服务条款,不对公共服务器、他人服务器进行挂机、刷物品、轰炸聊天、杀害其他玩家等操作。
- 使用独立测试账号和独立游戏 ID,不要让实验代码污染主力账号。
- 不写自动攻击玩家、自动刷稀有物品、自动规避反作弊检测等破坏性逻辑。
- 保存好服务器授权信息,不要把机器人运行在不受你控制的服务器上。
这不是道德说教,而是工程常识。机器人一旦写出"无限制自动行动"逻辑,它不会像人一样有耐心和道德约束,一个小 bug 就可能让它在服务器里疯狂挖方块、追着玩家打。这样的 Bot 无论是在技术上有多少可行性,在实际场景里都没有部署价值。
8.2 工程化建议
从第一版开始,就不要把所有代码写在一个 bot.js 里。可以先分出三个模块:config.js 管理服务器配置,bot.js 管理连接生命周期,tasks.js 管理具体任务。配置项应该放在独立文件中,因为服务器地址、用户名、端口这些信息是可变的,直接硬编码在代码里,换一个测试服务器就要改代码。
javascript复制// 文件路径:mc-bot/config.js
module.exports = {
host: '127.0.0.1',
port: 25565,
username: 'BotPlayer01',
auth: 'offline',
reconnectMinDelay: 3000,
reconnectMaxDelay: 60000
}
在任务编排上,优先用状态机和任务队列,而不是在事件回调里堆叠大量 if/else。一个简单的实现思路是维护一个数组作为任务队列,每次只执行队首任务,任务完成后自动出队。这样"先走到矿井,再挖矿,再回到基地"这类复合任务就可以表达成可复现的流程,而不是十几个嵌套回调。
还要注意日志。每次动作执行前后都要输出日志,内容包括时间戳、事件名、当前坐标、目标对象。日志是协议级机器人最重要的排错工具,因为你看不到画面,只能通过日志还原机器人的"感知"和"决策"。
8.3 性能与版本管理
mineflayer 是单线程 Node.js 程序,实体越多、区块越多,CPU 占用越高。在 physicsTick 回调里做重计算,或在每次聊天事件里遍历全部实体,都会拖垮性能。建议所有高频回调保持精简,把耗时逻辑放到队列或低频定时器里执行。
版本管理也很重要。lockfile 要提交到 Git,README 中记录你用的 Minecraft 服务器版本、mineflayer 版本、mineflayer-pathfinder 版本。Minecraft 协议更新频繁,mineflayer 主版本升级往往伴随 API 变化,生产环境的依赖升级不要直接 npm update,应该先看 release notes 再决定。
9. 总结与后续学习方向
如果你按照第 3 章到第 8 章的顺序一步步跑下来,你会得到一个能自动上线、响应聊天指令、搜索方块、挖掘目标、攻击敌对实体、自动寻路并断线重连的小机器人。相比一开始只写一个"能登录"的脚本,这套体系已经接近一个可以长时间运行的自动化任务原型。
给你的下一步建议很具体:先别急着加更多功能,让这只机器人在本地测试服务器里稳定跑两天,收集事件日志,观察事件时序。你会发现协议级自动化最大的门槛从来不是某个 API 不会用,而是你还没有建立起对事件时序和状态切换的直觉。把第一版做成"少而稳",比做成"多而乱"更有价值。
如果还想深入,建议按这个顺序继续探索:先读 mineflayer 的事件列表,理解每个事件代表的服务端行为;再研究 Minecraft Java 版协议的数据包结构,你会更清楚 bot.chat 背后到底发生了什么;最后可以关注寻路算法本身,因为 pathfinder 只是把 A* 思想封装好了,理解它之后,你能把这个能力迁移到其他机器人或自动化项目中。MinecraftBot 制作记录到这里并不是终点,它更像是一个通往网络协议和自动化工程的门把手。
