Mineflayer 新手实战教程:从零开始用 JavaScript 创建 Minecraft 机器人
发布时间:2026/9/28 6:26:50来源:尧图网络
游戏开发【免费下载链接】mineflayerCreate Minecraft bots with a powerful, stable, and high level JavaScript API.项目地址https://gitcode.com/gh_mirrors/mi/mineflayer点击查看免费下载本篇教程是 Mineflayer 项目官方入门指南的中文深度版本面向完全不懂编程的读者也适合已有 Node.js 基础、想快速上手机器人开发的开发者。读完本文你将掌握搭建 Node.js 与 NPM 开发环境、用createBot()连接任意 Minecraft 服务器并登录、监听spawn/health等事件驱动机器人行为、通过回调与 Promise 正确处理craft()等异步操作、用正则表达式把自定义聊天格式解析为事件以及在 Android 设备Termux上运行机器人。教程中所有 API 用法均有当前仓库源码佐证可直接复制运行。介绍这是 Mineflayer 的入门教程即使你对编程一无所知也能跟着学会。如果你已经熟悉 Node 和 NPM可以直接跳到 创建机器人 一节否则请从 JavaScript 基础知识 开始。Mineflayer 是一个用稳定、高层级 JavaScript API 创建 Minecraft 机器人的库见 package.json它把 Minecraft 协议封装成面向对象的接口你写的代码通过bot对象与游戏世界交互底层协议细节由minecraft-protocol等依赖处理。基础以下几节讲解开始使用 Mineflayer 前需要知道的基本概念。JavaScript 基础知识安装 Node本节学习 JavaScript、Node 和 NPM 的基础知识。JavaScript常缩写为 JS是一门为 Web 设计的编程语言网页上绝大部分交互功能都由它实现Node.js常简称为 Node则让 JavaScript 可以在浏览器之外运行。因此开始之前的第一步是安装 Node。安装完成后打开命令行终端输入node -v如果安装正确会返回一个版本号如果提示找不到命令请重新安装。当前仓库对运行环境有明确要求package.json中的engines字段为node 22且 index.js 在启动时会检查 Node 主版本低于 22 会直接报错退出所以请务必安装 Node 22 或更高版本。有了 Node 之后写代码还差一样东西虽然任何文本编辑器都能写 JavaScript但使用 IDE集成开发环境会轻松得多——它能给出代码补全建议、提示潜在问题。推荐从 Visual Studio CodeVSCode开始。安装配置好 VSCode 后新建一个文件以.js结尾保存例如bot.js这样 VSCode 就知道你在写 JavaScript 并给出正确的提示。JavaScript 变量首先输入以下内容const test 5这会创建一个名为test的变量并赋值为5。变量用于保存数据供后面的代码使用。保存文件后运行代码打开终端或在 VSCode 中打开新终端用cd命令导航到文件所在目录例如cd Documents/javascript然后执行node filename.js如果一切正确屏幕上不会显示任何东西下一节会教你如何打印输出。一般来说定义变量时应该优先使用const而不是let用const定义的变量之后无法被修改是常量JavaScript 引擎知道该变量的值不会变化可以让代码运行得更高效。当然如果需要可修改的变量仍要使用letconst test 5 // eslint-disable-next-line test 10 // 这行代码无效第二行是无效的因为test变量不能被重新赋值。想让代码更容易被别人包括未来的自己理解可以使用注释//之后的内容会被 JavaScript 完全忽略。显示输出很多时候你想查看变量的当前值确认程序运行是否正确这可以通过把变量打印到终端来实现。在 JavaScript 中使用console.log()函数const test 5 console.log(test)保存并运行后你应该看到5JavaScript 函数接下来学习函数。函数是一段可以在代码中多次复用的代码块省去重复输入相同代码的麻烦const addition (a, b) { return a b } const test1 addition(5, 10) const test2 addition(1, 0) console.log(test1) console.log(test2)被称为箭头操作符用来定义函数。箭头操作符之前是参数列表圆括号()内、用逗号分隔的就是参数参数是你传给函数的变量函数可以用它们工作。箭头操作符之后是函数体即花括号{}内的全部代码这里放函数的实现逻辑。函数定义完成后把它赋给一个变量来命名这里叫addition。这段代码把参数a和b相加然后返回结果。函数定义时函数体不会立即执行要运行函数必须调用它用函数名加圆括号即addition()。addition需要 2 个参数把它们放进圆括号、用逗号分隔传入addition(1, 2)。当函数执行完毕可以想象函数调用被其返回值替换所以let test1 addition(5, 10)相当于let test1 result你不会真的看到这个过程但这样理解概念很有帮助。有时你会看到function addition() {}这种写法它和箭头函数表达的意思相同但() {}是更推荐的写法。上面的代码输出15 1JavaScript 数据类型到目前为止我们只处理过数字但 JavaScript 能处理更多变量类型字符串string一段可包含多个字符的文本用引号定义const string This is a string // 字符串类型数组array内部可以容纳多个变量的类型用方括号[]定义const array [1, 2, 3] // 数组类型对象object本质上是一种增强型数组后面教程会详细讲用花括号{}定义const object {} // 对象类型函数function函数也是一种独立的类型const adder (a, b) { return a b } // 函数类型布尔boolean只能取true或falseconst boolean true // 布尔类型未定义undefined当某样东西还没有被定义时它的类型是undefinedlet nothing // 未定义类型 const notDefined undefined // 未定义类型If 语句有时你想根据某个条件执行不同的操作可以用 if 语句实现const name Bob if (name Bob) { console.log(你的名字是 Bob) } else if (name Alice) { console.log(你的名字是 Alice) } else { console.log(你的名字不是Bob或Alice) }if 语句用if关键字创建后面圆括号()里是条件花括号{}里是执行体。条件必须能计算成布尔值。这里用了相等操作符如果它前面的值与后面的值相同则为true否则为false。条件为true时执行体内的代码。你可以用 else-if 和 else 把多个 if 语句串联起来else-if 可以有任意多个但 if 和 else 只能各有一个else 语句只在它之前所有串联的条件都为false时执行。循环循环用于重复执行某段代码直到某个条件满足let countDown 5 while (countDown 0) { console.log(countDown) countDown countDown - 1 // 从1递减 } console.log(已完成!)上述代码将打印5 4 3 2 1 已完成!while循环有条件和函数体两部分。代码执行到循环处时先检查条件为true则执行函数体函数体执行完后再次检查条件如此往复直到条件检查为false。每轮循环这段代码打印当前的countDown值然后把它减 1。第 5 次循环后条件0 0为false代码继续往下走。for循环也很常用与while略有不同for (let countDown 5; countDown 0; countDown countDown - 1) { console.log(countDown) }for循环有 3 个部分用分号分隔而不是只有条件第一部分let countDown 5只在循环开始时执行一次第二部分countDown 0是条件与while循环相同第三部分countDown countDown - 1在每轮循环结束后执行。如果要对数组中的每个元素做点事情for of循环很有用const array [1, 2, 3] for (const item of array) { console.log(item) }for of循环需要在of之前声明一个变量用于访问当前元素of之后是包含其他变量的东西通常是数组也可以是某些对象。循环对数组中的每个元素执行一次函数体每轮循环item变量就是数组中的当前元素。Node 包管理器最后需要学会使用 NPMNode 包管理器。NPM 会随 Node 自动安装用来获取别人创建的有用包。你可以在它的网站上搜索包然后在终端用npm install命令安装。例如安装 Mineflayernpm install mineflayer然后Node 用require()函数访问已安装的模块const mineflayer require(mineflayer)之后mineflayer变量就可以用来访问 Mineflayer 的全部功能了。创建机器人现在你了解了 JavaScript、Node 和 NPM 的基础可以开始创建你的第一个机器人了如果你对上面任何术语还不熟悉请回到 JavaScript 基础知识 一节。下面是创建 Mineflayer 机器人所需的绝对最少代码const mineflayer require(mineflayer) const bot mineflayer.createBot()运行这个示例你会发现程序不会自己停止——想停止正在运行的程序按Ctrlc。这个机器人还不太有用因为默认它会连接你本机运行、端口为 25565 的 Minecraft 服务器。如果你想选择要连接的服务器需要传入一些选项const mineflayer require(mineflayer) const options { host: localhost, // 将此项更改为所需的ip port: 25565 // 将此项更改为所需的端口 } const bot mineflayer.createBot(options)从源码看createBot()还有很多默认值会一并生效。在 lib/loader.js 中可以看到username默认是Playerversion默认是false表示连接时自动检测服务器版本loadInternalPlugins默认为true这意味着机器人会默认加载仓库 lib/plugins 目录下的几十个内置插件聊天、挖掘、合成、战斗、物理、背包等。返回的bot本身是一个 Node.jsEventEmitter对象后面的事件监听全都建立在这之上。JavaScript 对象花括号{}用来创建对象。对象包含键值对冒号:之前是键之后是该键的值。键可以用来取出对应的值多个键值对之间用逗号分隔const object { number: 10, another: 5 } console.log(object.number) // 这将打印值10这个写法常被用来创建命名参数好处是你不需要使用全部可用选项而且顺序无关紧要。值可以是任何东西甚至是另一个对象如果值是函数通常称它为这个对象的方法。你也可以内联创建对象const bot mineflayer.createBot({ host: localhost, port: 25565 })登录不传任何参数时机器人名字为Player只能登录离线服务器破解版与开放局域网。如果给createBot提供username选项它会用该用户名登录仍然只能在离线服务器。要登录特定账号必须同时提供username和passwordconst bot mineflayer.createBot({ host: localhost, port: 25565, username: Player, password: password })命令行参数如果别人喜欢你的机器人但想用在不同的服务器、不同的账号上怎么办这意味着每个人都要修改代码里的服务器地址和登录设置而且在代码里共享密码当然也不是好主意。为了解决这个问题很多人使用命令行参数const bot mineflayer.createBot({ host: process.argv[2], port: parseInt(process.argv[3]), username: process.argv[4], password: process.argv[5] })这样代码里就没有敏感数据了但怎么运行呢不再是node filename.js而是node filename.js host port username password。Node 会把整条命令行按空格自动拆分成一个数组这个数组就是process.argv。数组中的数据通过下标访问下标从 0 开始第 1 项第 2 项第 3 项第 4 项第 5 项第 6 项值nodefilename.jshostportusernamepassword下标[0][1][2][3][4][5]注意端口是字符串需要用parseInt()转成数字否则无法正确传给createBot。传递函数不只是数字、字符串这类基础变量可以作为参数函数也可以作为变量传递const welcome () { bot.chat(你好!) } bot.once(spawn, welcome)bot.once()方法接收 2 个参数第一个是事件名第二个是事件发生时调用的函数。记住传递函数时只用函数名不要带圆括号()。bot.chat()是向聊天框发送消息的方法。在 lib/plugins/chat.js 中可以看到它的实现bot.chat内部通过chatWithHeader(, message)发送消息如果消息过长会自动按聊天长度上限多数版本 256 字符不支持长聊天的版本为 100 字符自动分段发送。你还可以用匿名函数简化代码。匿名函数没有名字直接在原本放函数名的位置创建即使不用参数也要保留参数列表()和函数体{}bot.once(spawn, () { bot.chat(你好!) })spawn事件的具体触发时机可以看 lib/plugins/health.js当客户端收到update_health数据包且生命值大于 0 时机器人就会发出spawn事件随后进入游戏。所以用bot.once(spawn, ...)可以确保代码在进入服务器、可以行动之后才执行。监听事件bot对象有许多实用事件完整清单见 docs/api.md。你可以用bot.on()或bot.once()方法监听事件它们接收事件名和一个函数。要移除特定监听器使用bot.removeListener()方法。bot.on(eventName, listener)每次名为eventName的事件触发时都执行listener函数。bot.once(eventName, listener)事件第一次触发时只执行一次listener函数。bot.removeListener(eventName, listener)移除名为eventName事件的指定listener。要使用它你需要用function myNamedFunc() {}定义函数或用const myNamedFunc () {}把函数放进变量然后把myNamedFunc传给 listener 参数——匿名函数无法被移除。不只bot对象有事件Chest、Furnace、Dispenser、EnchantmentTable、Villager等对象也都有自己的事件。它们对应仓库 lib/plugins 目录下的chest.js、furnace.js、villager.js等模块——当你打开一个箱子、熔炉或与村民交互时这些对象会被创建并触发相应事件。回调回调callback是你传给另一个函数的函数预期在那个函数结束时被回调。在 Mineflayer 中回调常用于处理错误bot.consume((error) { if (error) { // 这将检查是否发生错误 console.log(error) } else { console.log(Finished consuming) } })上面的代码会尝试让机器人吃掉当前手持的物品。当进食结束时传入的函数被调用我们可以在其中继续做想做的事如果发生错误函数同样会被调用。bot.consume()的完整语义在 lib/plugins/inventory.js 中有详细实现当生命值已满food 20且处于生存模式、手持的不是药水/牛奶等特殊物品时它会拒绝执行进食期间bot.usingHeldItem为true。对应的测试在 test/externalTests/consume.js 中测试用面包演示了饥饿状态可进食、满腹状态报错的完整状态流转。正确与错误的做法下面是一个把橡木原木合成为橡木木板、再把木板合成为木棍的机器人示例。错误的做法 ❌const plankRecipe bot.recipesFor(5)[0] // 获取物品 id 5橡木木板的第一个配方 bot.craft(plankRecipe, 1) // ❌ 开始合成橡木木板 const stickRecipe bot.recipesFor(280)[0] // 获取物品 id 280木棍的第一个配方 bot.craft(stickRecipe, 1) // ❌ 开始合成木棍回调的正确方法 ✔️const plankRecipe bot.recipesFor(5)[0] bot.craft(plankRecipe, 1, null, (error) { // 当 bot.craft(plankRecipe, ...) 完成后这个回调被调用我们继续执行。✔️ if (error) { // 检查是否发生了错误 console.log(error) } else { const stickRecipe bot.recipesFor(280)[0] bot.craft(stickRecipe, 1, null, (error) { // 当 bot.craft(stickRecipe, ...) 完成后这个回调被调用我们继续执行。✔️ if (error) { // 检查是否发生了错误 console.log(error) } else { bot.chat(Crafting Sticks finished) } }) } })错误做法之所以错误是因为bot.craft()被调用后代码会继续往下执行而机器人还在合成中——等代码执行到第二个bot.craft()时第一次合成很可能还没完成所需的材料还不可用。回调可以解决这个问题因为回调只在bot.craft()结束后才被调用。关于bot.craft()方法从 lib/plugins/craft.js 的实现看bot.craft(recipe, count, craftingTable)本身就是async函数它内部会循环执行craftOnce自动处理点击合成格放入材料、取走产物、关闭合成台窗口的完整流程bot.recipesFor(itemType, metadata, minResultCount, craftingTable)则只返回当前背包材料足够的配方。另外英文版官方教程docs/tutorial.md展示了基于 Promise 的等价写法由于craft返回 Promise可以直接await bot.craft(plankRecipe, 1, null)再执行下一步并推荐用require(minecraft-data)(bot.version)按物品名称查找 id例如mcData.itemsByName.oak_planks.id这比硬编码数字 id如 5、280更可读、更健壮。两种写法任选其一即可。高级下面这些概念不是创建 Mineflayer 机器人所必需的但对理解和开发更高级的机器人很有帮助。我们假定你已经掌握了前面的 基础 教程。异步性在 JavaScript 中异步是一个重要概念。默认情况下JavaScript 会逐行执行代码当前行完成后才进入下一行这被称为阻塞。但有些操作耗时较长你不想让整个程序阻塞等待它完成。与文件系统交互就经常使用异步因为读写大文件可能很耗时。const myPromise new Promise((resolve, reject) { setTimeout(() { resolve(Success!) // 耶一切都很顺利 }, 1000) }) myPromise.then((successMessage) { console.log(successMessage) }) myPromise.catch((error) { console.log(error) })上面的代码用到了 Promise。Promise 承诺它最终一定会完成。传给 Promise 的函数总是有 2 个参数resolve函数和reject函数。如果 Promise 成功会调用resolve否则调用reject。这段代码使用了setTimeout它会在指定毫秒数这里是 1000后调用传入的函数。然后你可以用.then(function)告诉 Promise 成功时该做什么用.catch(function)告诉它失败时该做什么。.then和.catch还可以与 Promise 链式书写让代码更简洁const myPromise new Promise((resolve, reject) { setTimeout(() { resolve(Success!) // 耶一切都很顺利 }, 1000) }).then((successMessage) { console.log(successMessage) }).catch((error) { console.log(error) })Promise 的异步机制与前面 监听事件 一节的bot.once(spawn, ...)是同一个心智模型你不等待事件而是告诉系统当它发生时做什么。Mineflayer 内部大量使用这种模式比如bot.consume()、bot.craft()都返回 Promise这也解释了为什么英文版教程用await来写合成流程。遍历对象循环 一章讲过的for of循环也可以用来遍历对象。如果我们有下面这个对象const obj { a: 1, b: 2, c: 3 }下面这段代码遍历对象的所有值for (const value of Object.values(obj)) { console.log(value) }1 2 3这段代码遍历对象的所有键for (const key of Object.keys(obj)) { console.log(key) }a b c你还可以同时遍历键和值这需要先对变量做解构destructuringfor (const [key, value] of Object.entries(obj)) { console.log(key , value) }a, 1 b, 2 c, 3这些循环之所以可行是因为Object.values(obj)和Object.keys(obj)都返回一个数组分别是对象的值数组和键数组Object.entries(obj)返回的数组里每一项都是一个含 2 个元素的小数组一个键和它对应的值。需要注意的是与Object.values()和Object.keys()不同Object.entries()不保证顺序与对象定义时的顺序一致。还有一种for in循环但你大多数时候应该用for of而不是for in两者有本质区别for in遍历的是对象的键而不是值对数组来说是下标而且它不仅遍历自身的键还会遍历从其他对象继承来的键这可能让人困惑或并非你所需。总之优先使用for of别把两者搞混。从聊天中创建事件你可以用bot.chatAddPattern()方法从聊天中创建自定义事件。这对于聊天格式经常变化的 Bukkit 服务器特别有用。bot.chatAddPattern()方法接收三个参数pattern匹配聊天的正则表达式regexchatType模式匹配时机器人发出的事件名例如chat或whisperdescription可选描述这个模式的用途你可以在pattern中加入分组Groups监听器会把捕获到的分组按顺序展开为回调函数的参数。不过需要提醒从源码看chatAddPattern在 lib/plugins/chat.js 中已被标记为废弃deprecated其实现是bot.chatAddPattern (patternValue, typeValue) bot.addChatPattern(typeValue, patternValue, { deprecated: true })事件名直接使用传入的名字。当前推荐使用的是新 APIbot.addChatPattern(name, pattern, options)监听的事件名变为chat:name英文版教程 docs/tutorial.md 已改用新 API。两种写法都可用新代码建议优先用新 API。例子回答你好 机器人这里我们创建一个机器人回应另一位玩家说的你好。旧 API与中文版教程一致bot.chatAddPattern( /(helo|hello|Hello)/, hello, Someone says hello ) const hi () { bot.chat(Hi!) } bot.on(hello, hi)等价的新 API 写法bot.addChatPattern( hello, /(helo|hello|Hello)/, { description: Someone says hello } ) const hi () { bot.chat(Hi!) } bot.on(chat:hello, hi)自定义聊天基于自定义聊天格式创建事件。自定义聊天示例[Player] 路人甲 你好 [Admin] 李四 Hi [Player] 法外狂徒张三 焯!我卡住了 [Mod] Jim 我马上到bot.chatAddPattern( /^\[(.)\] (\S) (.)$/, my_chat_event, Custom chat event ) const logger (rank, username, message) { console.log(${username} 说 ${message}) } bot.on(my_chat_event, logger)正则表达式^\[(.)\] (\S) (.)$的含义^匹配行首\[(.)\]匹配方括号内的任意内容这里是玩家前缀/权限组如Player、Admin、Mod并捕获为分组 1(\S)匹配一串非空白字符玩家名并捕获为分组 2匹配分隔符(.)$匹配行尾剩余内容消息正文并捕获为分组 3。因此logger的三个参数rank、username、message会依次接收到这三个分组。这个机制在源码中的工作流程是聊天消息到达后机器人内部先发出messagestr事件lib/plugins/chat.js 会用你注册的所有正则去测试消息字符串匹配成功就按注册顺序把捕获的分组展开成参数发出你指定的事件。仓库还内置了bot.addChatPatternSet(name, patterns, opts)可以用一组正则去匹配一条消息并支持repeat是否重复匹配与parse是否把每个模式的分组分别传参选项适合更复杂的聊天解析场景。FAQ如何在 Android 上运行机器人下面是在 Android 设备上用 Termux 运行机器人的快速设置教程。安装 Termux安装 Termux 并启动它。环境设置安装 Node.jspkg update -y pkg install nodejs -y❗️ 在应用设置中允许 Termux 的存储权限。在内部存储上创建新文件夹cd /sdcard mkdir my_scripts cd my_scripts安装 mineflayernpm install mineflayer现在你可以把所有的脚本复制/存储到内部存储中的my_scripts文件夹里了。启动你的机器人要启动机器人使用 Node 运行脚本名称node script_name.js❗️ 每次打开 Termux 时你都必须在启动机器人之前把当前工作目录cwd切换到/sdcard/my_scriptscd /sdcard/my_scripts需要注意Android 上的 Node 版本同样要满足 Mineflayer 的要求Node ≥ 22见 package.json 的engines字段pkg install nodejs安装的版本较旧时请通过pkg upgrade nodejs或 Termux 官方提供的新版本渠道更新。延伸阅读完整 API 参考与全部事件列表docs/api.md更多可直接运行的示例脚本examples 目录如 examples/chat_parsing.js、examples/chest.js中文版问答docs/zh/FAQ.md中文 API 文档docs/zh/api.md想为机器人添加自定义模块可以参考 lib/plugins 下各插件的写法以及插件加载机制 lib/plugin_loader.js赞分享游戏开发【免费下载链接】mineflayerCreate Minecraft bots with a powerful, stable, and high level JavaScript API.项目地址https://gitcode.com/gh_mirrors/mi/mineflayer点击查看免费下载相关推荐SGN项目揭秘终极多态二进制编码器如何绕过安全检测SGN项目揭秘终极多态二进制编码器如何绕过安全检测 SGNShikata ga nai是一款基于Go语言开发的终极多态二进制编码器通过先进的混淆和加密技Mineflayer终极指南如何轻松创建远程控制的Minecraft机器人Mineflayer终极指南如何轻松创建远程控制的Minecraft机器人 想要让你的Minecraft世界更加智能化吗 Mineflayer是一个强大游戏开发Mineflayer完整教程构建智能Minecraft机器人的终极方案Mineflayer完整教程构建智能Minecraft机器人的终极方案 Mineflayer是一个基于Node.js的强大开源库专门用于创建智能Minecr游戏开发上一篇Electron Webpack Dashboard现代化 Webpack 构建监控桌面应用下一篇Fluid Paint 项目推荐创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网