You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mineflayer(Node.js)实现玩家跟随功能时出现库源码错误

问题:使用mineflayer-pathfinder实现跟随玩家时触发TypeError错误

我尝试用Node.js的mineflayer库做一个自动跟随玩家的机器人,但运行时触发了mineflayer-pathfinder库的错误。我的代码如下:

const mineflayer = require('mineflayer');
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder')
const GoalFollow = goals.GoalFollow

const bot = mineflayer.createBot({
  host: 'PRIVATE',
  username: 'TRASHCAN'
})

bot.loadPlugin(pathfinder)

function followPlayer() {
  const player = p => p.type === "player";
  const mcData = require('minecraft-data')(bot.version);
  const movements = new Movements(mcData);
  
  bot.pathfinder.setMovements(movements);
  const goal = new GoalFollow(player.entity, 3)
  bot.pathfinder.setGoal(goal, true);

}
const prefix = ",s"
const password = 'REMOVED'
const login = `/login ${password}`

const { mineflayer: mineflayerViewer } = require('prismarine-viewer')
bot.once('spawn', () => {
  mineflayerViewer(bot, { port: 3007, firstPerson: true }) // port is the minecraft server port, if first person is false, you get a bird's-eye view
  bot.chat(login)
  bot.on('whisper', (username, message) => {
    if (message.startsWith(prefix) && username === 'Hitrocol') {
        bot.chat(message.split(',TRASHCAN_')[1]);
    }
    if (message.content === ',TRASHCAN_LOGIN' && username === 'Hitrocol') {
        bot.chat(login)
    }
  })
})

function lookAtNearestPlayer() {
    const playerFilter = (entity) => entity.type === 'player'
    const playerEntity = bot.nearestEntity(playerFilter);

    if (!playerEntity) return;
    const pos= playerEntity.position;
    bot.lookAt(pos);
}

bot.on('physicsTick', lookAtNearestPlayer);
bot.on('physicsTick', followPlayer);

预期机器人能自动跟随玩家,但出现以下错误(mineflayer和mineflayer-pathfinder都是最新版本):

/Users/aarav/node_modules/mineflayer-pathfinder/lib/movements.js:42
    this.blocksCantBreak.add(registry.blocksByName.chest.id)
                                      ^

TypeError: 无法读取未定义的属性(读取'blocksByName')
    at new Movements (/Users/aarav/node_modules/mineflayer-pathfinder/lib/movements.js:42:39)
    at EventEmitter.followPlayer (/Users/aarav/Downloads/codingshit/untitled folder/index.js:15:21)
    at EventEmitter.emit (node:events:529:35)
    at tickPhysics (/Users/aarav/node_modules/mineflayer/lib/plugins/physics.js:81:11)
    at Timeout.doPhysics [as _onTimeout] (/Users/aarav/node_modules/mineflayer/lib/plugins/physics.js:70:7)
    at listOnTimeout (node:internal/timers:569:17)
    at process.processTimers (node:internal/timers:512:7)

Node.js v18.18.0

解决方案

错误原因分析

  1. Movements构造参数错误:新版mineflayer-pathfinder的Movements类需要传入bot实例作为第一个参数,而不是直接传mcData。
  2. 玩家实体获取错误:followPlayer里的player是一个过滤函数,不是实际的玩家实体,player.entity根本不存在,会导致GoalFollow初始化失败。
  3. 事件绑定不合理:把followPlayer绑定到physicsTick事件会被高频调用(每游戏 tick 一次),重复初始化Movements和设置路径,不仅浪费性能,还会引发异常。

修复后的代码

const mineflayer = require('mineflayer');
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder')
const GoalFollow = goals.GoalFollow

const bot = mineflayer.createBot({
  host: 'PRIVATE',
  username: 'TRASHCAN'
})

bot.loadPlugin(pathfinder)

// 初始化Movements(只需一次)
let movements;
bot.once('spawn', () => {
  const mcData = require('minecraft-data')(bot.version);
  movements = new Movements(bot, mcData); // 传入bot实例作为第一个参数
})

function followPlayer() {
  // 获取最近的玩家实体
  const playerFilter = (entity) => entity.type === 'player';
  const playerEntity = bot.nearestEntity(playerFilter);
  
  if (!playerEntity) {
    bot.pathfinder.setGoal(null); // 没有玩家时清空路径目标
    return;
  }

  bot.pathfinder.setMovements(movements);
  const goal = new GoalFollow(playerEntity, 3); // 传入实际的玩家实体
  bot.pathfinder.setGoal(goal, true);
}

const prefix = ",s"
const password = 'REMOVED'
const login = `/login ${password}`

const { mineflayer: mineflayerViewer } = require('prismarine-viewer')
bot.once('spawn', () => {
  mineflayerViewer(bot, { port: 3007, firstPerson: true })
  bot.chat(login)
  bot.on('whisper', (username, message) => {
    if (message.startsWith(prefix) && username === 'Hitrocol') {
        bot.chat(message.split(',TRASHCAN_')[1]);
    }
    if (message === ',TRASHCAN_LOGIN' && username === 'Hitrocol') { // 修正message.content的错误,whisper事件的message是字符串
        bot.chat(login)
    }
  })
})

function lookAtNearestPlayer() {
    const playerFilter = (entity) => entity.type === 'player'
    const playerEntity = bot.nearestEntity(playerFilter);

    if (!playerEntity) return;
    const pos = playerEntity.position;
    bot.lookAt(pos);
}

// 合理控制跟随逻辑的执行频率,避免高频重复调用
let tickCount = 0;
bot.on('physicsTick', () => {
  lookAtNearestPlayer();
  tickCount++;
  if (tickCount % 20 === 0) { // 每1秒(20个游戏tick)执行一次跟随逻辑
    followPlayer();
    tickCount = 0;
  }
});

额外修复点

  • 修正了whisper事件中的message.content错误:whisper事件的第二个参数message是字符串,不是对象,直接判断message === ',TRASHCAN_LOGIN'即可。
  • 将Movements的初始化移到spawn事件中,只执行一次,避免重复创建。
  • 调整followPlayer的调用频率,减少不必要的性能消耗。

内容的提问来源于stack exchange,提问作者Adelto isbest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:57:40