Skip to content

Repository files navigation

Minecraft Embodied AI Agent

A human-like companion AI that learns to follow and play with a player in Minecraft, trained with Behavioral Cloning + PPO reinforcement learning on Apple Silicon.

一个在 Minecraft 中学习跟随并陪伴玩家的类人智能体,基于行为克隆 + PPO 强化学习,运行于 Apple Silicon。


Demo / 效果展示

After 500K steps of PPO fine-tuning on top of behavioral cloning pre-training, the agent maintains 3–5 block follow distance across flat terrain and moderate obstacles, with smooth head movement and no mechanical snapping.

经过行为克隆预训练 + 500K 步 PPO 微调后,智能体能在平坦地形和一般障碍物环境中将跟随距离稳定保持在 3–5 格,头部转动自然,无机械式瞬间转向。

Metric / 指标 Result / 结果
BC validation action accuracy / BC 验证集动作准确率 81.5%
PPO training steps / PPO 训练步数 500,000
Stable follow distance / 稳定跟随距离 ~3.6–3.9 blocks / 格
Control loop frequency / 控制循环频率 20 Hz
End-to-end inference latency / 端到端推理延迟 < 50 ms
Hardware / 硬件 Mac mini M4 (16–24 GB unified memory)

Project Vision / 项目愿景

This is not a scripted pathfinding bot. The goal is to build a human-like digital companion that:

不是一个脚本寻路机器人。目标是构建一个类人的数字伙伴,能够:

  • Follow naturally — navigate complex 3D terrain (forests, hills, caves) without hard-coded rules. 自然跟随 — 无硬编码规则地在复杂 3D 地形中导航。
  • Move like a human — learned from real player recordings to produce organic movement, not grid-snapping. 像人一样移动 — 从真实玩家录制数据中学习,产生有机运动而非格子式位移。
  • Run on consumer hardware — entirely on a Mac mini M4 at 20 Hz, with headroom for future LLM slow-loop integration. 在消费级硬件上运行 — 全程在 Mac mini M4 上以 20 Hz 运行,并为未来接入 LLM 慢环预留空间。

Architecture Overview / 架构总览

┌─────────────────────────────────────────────────────────────┐
│                        Mac mini M4                          │
│                                                             │
│  ┌─────────────────┐   ZMQ PUB :5555    ┌────────────────┐  │
│  │  Mineflayer Bot │ ──────────────────► │  Python Agent  │  │
│  │  (Node.js)      │                    │                │  │
│  │  Headless       │ ◄────────────────── │  PPO Policy    │  │
│  │  bridge/bot.js  │   ZMQ REP :5556    │  PyTorch MPS   │  │
│  └────────┬────────┘    (action idx)    └────────────────┘  │
│           │                                                  │
│  ┌────────▼────────┐                                        │
│  │  Paper 1.20.1   │  ◄── WandererBot (PPO training target) │
│  │  Server         │  ◄── Fabric Mod  (BC data recording)   │
│  └─────────────────┘                                        │
└─────────────────────────────────────────────────────────────┘

Key design choice / 核心设计选择: No vision/CNN. The agent perceives the world through structured data only — a 9×9×9 block ID grid + kinematics + target vector. This keeps inference under 50 ms on M4 Metal (MPS) while the Minecraft server runs on the same machine.

无视觉/CNN。智能体仅通过结构化数据感知世界——9×9×9 方块 ID 网格 + 运动学 + 目标向量。这使推理在 M4 Metal (MPS) 上保持在 50ms 以内,同时 Minecraft 服务器也运行在同一台机器上。


Data Pipeline / 数据流水线

Phase 1: Data Collection / 第一阶段:数据采集
  Single-player (Fabric Mod) or
  Multiplayer observer (bridge/recorder.js)
         │
         ▼
  data/recordings/session_*.jsonl
         │
         ▼ convert_data.py (filters idle frames)
         │
  data/recordings/dataset.h5
         │
Phase 2: Behavioral Cloning / 第二阶段:行为克隆
         ▼ bc_train.py  (~5 min, 20 epochs)
         │
  models/bc_pretrained.pt   (val_acc = 81.5%)
         │
Phase 3: PPO Fine-tuning / 第三阶段:PPO 微调
         ▼ ppo.py --load bc_pretrained.pt  (~hours)
         │
  models/ppo_NNNNNNN.pt
         │
         ▼ eval.py (inference only)
  Live agent in-game / 游戏内实时运行

Observation Space / 观测空间

Field / 字段 Shape Description / 说明
grid [729] int16 9×9×9 block type IDs centered on bot, world-axis-aligned / 以 bot 为中心的 9×9×9 方块类型 ID,世界轴对齐
kinematics [6] float32 pitch/yaw (÷π), vx/vy/vz (÷10, clipped ±1), on_ground / 俯仰角/偏航角(÷π), 三轴速度(÷10,截断至 ±1), 是否落地
target [3] float32 ΔX/ΔY/ΔZ to follow target, clipped ±1 (raw ÷50) / 到跟随目标的 ΔX/ΔY/ΔZ,截断至 ±1(原始值 ÷50)

Block type IDs use the same registry (Registries.BLOCK.getRawId() in Fabric, block.type in Mineflayer) — max ~1057 in 1.20.1, with N_BLOCK_TYPES=1200 for safety.

方块类型 ID 使用相同的注册表(Fabric 中 Registries.BLOCK.getRawId(),Mineflayer 中 block.type)——1.20.1 中最大约 1057,为保险起见设 N_BLOCK_TYPES=1200


Action Space / 动作空间 (12 discrete / 12 个离散动作)

ID Action / 动作
0 forward / 前进
1 back / 后退
2 left / 左平移
3 right / 右平移
4 jump / 跳跃
5 forward + sprint / 前进 + 疾跑
6 forward + left / 前进 + 左
7 forward + right / 前进 + 右
8 yaw −0.3 rad / 偏航 −0.3 弧度(左转头)
9 yaw +0.3 rad / 偏航 +0.3 弧度(右转头)
10 pitch −0.2 rad / 俯仰 −0.2 弧度(抬头)
11 pitch +0.2 rad / 俯仰 +0.2 弧度(低头)

Policy Network / 策略网络

Input / 输入:
  grid [B, 729]  →  Embedding(1200, 16)  →  flatten  →  [B, 11664]
  kinematics [B, 6]
  target [B, 3]
  concat → [B, 11673]

Backbone / 主干:
  Linear(11673→512) + LayerNorm + ReLU
  Linear(512→256)   + LayerNorm + ReLU
  Linear(256→128)   + ReLU

Output heads / 输出头:
  Actor:  Linear(128→12)   → softmax → action probabilities
  Critic: Linear(128→1)    → state value

Total parameters / 总参数量: ~6.15M
Device / 设备: MPS (Apple Silicon Metal)

Reward Function / 奖励函数

Component / 组件 Weight / 权重 Description / 说明
Follow distance reward / 跟随距离奖励 ×1.0 Sweet spot 2–5 blocks (land), 3–8 blocks (water) / 甜区陆地 2–5 格,水中 3–8 格
PBRS shaping / 势能塑形奖励 ×0.3 Potential-based reward shaping toward target / 基于势能的向目标奖励塑形
Stuck penalty / 卡住惩罚 ×1.0 Penalize low velocity near target / 靠近目标时速度过低给予惩罚
View smoothness penalty / 视角平滑度惩罚 ×1.0 Penalize oscillating head movement / 惩罚视角振荡
Cliff penalty / 坠落惩罚 ×1.0 Penalize airborne without jump input / 惩罚无跳跃输入的离地状态

Rewards are normalized online with Welford algorithm and clipped to ±2.0. PPO uses RewardNormalizer (Welford), clip ±10 on normalized values.

奖励使用 Welford 在线算法归一化并截断至 ±2.0。PPO 的 RewardNormalizer(Welford)对归一化值截断 ±10。


PPO Training Config / PPO 训练配置

Hyperparameter / 超参数 Value / 值
total_timesteps 500,000
n_steps 512
batch_size 64
n_epochs 4
gamma 0.99
gae_lambda 0.95
clip_range 0.2
ent_coef 0.01
learning_rate 3e-4 (linear decay)
save_every 50,000 steps

File Structure / 文件结构

minecraft-agent/
├── agent/
│   ├── policy.py          # PolicyNetwork (PPO) + BCPolicyNetwork (BC)
│   ├── ppo.py             # CleanRL-style PPO trainer with RewardNormalizer
│   ├── bc_train.py        # Behavioral cloning trainer
│   ├── bc_eval.py         # BC model evaluation
│   ├── convert_data.py    # JSONL → HDF5 converter (filters idle frames)
│   ├── env.py             # Gymnasium environment, 8-component reward
│   └── eval.py            # Inference-only script (no training)
│
├── bridge/
│   ├── bot.js             # RL agent bot — ZMQ PUB:5555 + REP:5556
│   ├── wanderer.js        # Wandering bot — PPO training target
│   ├── recorder.js        # Multiplayer observer recorder (per-player JSONL)
│   ├── run_bots.sh        # Launch bot.js + wanderer.js together
│   └── sensors/
│       └── grid.js        # getGrid9x9x9 / getTargetDelta / getKinematics
│
├── fabric-mod/
│   └── src/main/java/com/mcagent/recorder/
│       └── DataRecorderMod.java   # Single-player tick recorder → JSONL
│
├── mr_server/
│   ├── server.properties  # offline-mode, view-distance=4, no monsters
│   ├── ops.json           # AgentBot, WandererBot OP(人类玩家请本地自行 /op 或编辑 ops)
│   └── spigot.yml         # moved-too-quickly-multiplier=100.0 (anti-kick)
│
├── data/recordings/       # session_*.jsonl + dataset.h5
├── models/                # bc_pretrained.pt + ppo_NNNNNNN.pt checkpoints
├── runs/                  # TensorBoard event files (bc/ and ppo/)
│
├── start_server.sh        # Start Paper 1.20.1 server
├── start_bot.sh           # Start bot.js(默认跟随目标:WandererBot,可用 MC_TARGET 覆盖)
├── run_training.sh        # Auto-resume PPO: finds latest checkpoint, restarts on failure
├── server_setup.sh        # Full Ubuntu/Debian deployment with systemd
└── test_zmq.py            # ZMQ diagnostic script

ZMQ Communication Protocol / ZMQ 通信协议

bot.js  ──PUB:5555──►  Python agent (env.py)
         every physicsTick (50ms / 20Hz)
         payload: { t, position, kinematics, grid, target_delta, health, food }

Python agent (env.py)  ──REP:5556──►  bot.js
         discrete action index 0–11
         reply: { ok: true }

SUB socket: zmq.CONFLATE=1 — only the latest frame is kept, stale frames dropped.
IPC file:   /tmp/agentbot_pos.json — written every tick by bot.js,
            read by Fabric Mod to compute target_delta in single-player mode.

Quick Start / 快速开始

Prerequisites / 前置条件

  • macOS with Apple Silicon (M1/M2/M3/M4)
  • Java 17+ (for Fabric mod build and Paper server)
  • Node.js 20 LTS
  • Python 3.11
  • Prism Launcher (for running Fabric client with the recorder mod)

1. Server / 服务器

bash start_server.sh
# Paper 1.20.1 starts on localhost:25565 (offline mode)

2. Python environment / Python 环境

python3.11 -m venv .venv
source .venv/bin/activate
pip install torch torchvision  # PyTorch with MPS support
pip install gymnasium pyzmq h5py numpy

3. Node.js environment / Node.js 环境

cd bridge
npm install

4. Fabric Mod (data collection) / Fabric Mod(数据采集)

cd fabric-mod
./gradlew build
# Copy build/libs/data-recorder-1.0.0.jar to Prism Launcher mods folder
# 默认写入路径由 Fabric Mod 固定为 ~/project/minecraft/data/recordings/session_*.jsonl(见 DataRecorderMod.java);与仓库目录可不同,需自行同步或改源码路径

Training Workflow / 训练流程

Step 1: Collect behavioral cloning data / 第一步:采集行为克隆数据

Play Minecraft with the Fabric mod installed. Each session writes a .jsonl file automatically. Aim for at least 1–2 hours of follow/walk gameplay.

安装 Fabric Mod 后正常游玩 Minecraft,每次会话自动写入 .jsonl 文件。建议采集至少 1–2 小时的跟随/行走游戏数据。

# Alternatively, record from multiplayer observer perspective:
# 或者从多人模式旁观视角录制:
cd bridge && node recorder.js

Step 2: Convert data / 第二步:转换数据

source .venv/bin/activate
python agent/convert_data.py data/recordings/session_*.jsonl
# Output: data/recordings/dataset.h5
# Idle frames (no key pressed) are filtered automatically.
# 输出:data/recordings/dataset.h5(自动过滤无按键的空闲帧)

Step 3: BC pre-training / 第三步:行为克隆预训练

python agent/bc_train.py --data data/recordings/dataset.h5
# ~5 minutes on M4. Saves to models/bc_pretrained.pt
# 在 M4 上约需 5 分钟。保存至 models/bc_pretrained.pt

Step 4: Start the bots / 第四步:启动机器人

# Terminal 1: RL agent bot + wanderer bot
# 终端 1:RL 智能体机器人 + 漫游目标机器人
cd bridge && bash run_bots.sh

Step 5: PPO training / 第五步:PPO 训练

# Terminal 2:
source .venv/bin/activate

# Fresh start from BC weights:
# 从 BC 权重开始:
python agent/ppo.py --load models/bc_pretrained.pt

# Or auto-resume from latest checkpoint (recommended for overnight runs):
# 或自动从最新检查点续训(推荐用于无人值守过夜训练):
bash run_training.sh

Step 6: Monitor / 第六步:监控训练

tensorboard --logdir ./runs
# Open http://localhost:6006 in browser

Step 7: Run the trained agent / 第七步:运行训练好的智能体

# Terminal 2 (instead of ppo.py):
# 终端 2(替换 ppo.py):
source .venv/bin/activate
python agent/eval.py --load models/ppo_0500000.pt

Technical Notes / 技术说明

Key implementation details / 关键实现细节

  • BC key order / BC 键序:Fabric mod writes [W, S, A, D, Jump, Sprint]. bc_train.py unpacks as W, S, A, D, J, SP — note S before A. / Fabric Mod 写入顺序为 [W, S, A, D, Jump, Sprint]bc_train.pyW, S, A, D, J, SP 解包——注意 S 在 A 前面。
  • Pitch/Yaw units / 俯仰/偏航单位:Fabric mod converts Java getYaw()/getPitch() (degrees) to radians before writing. Mineflayer provides radians natively. Both consistent. / Fabric Mod 将 Java 的度数单位转换为弧度后写入,Mineflayer 原生提供弧度。两者一致。
  • Anti-cheat / 反作弊:AgentBot runs in creative mode. spigot.yml sets moved-too-quickly-multiplier: 100.0 to prevent kick on fast RL moves. / AgentBot 以创意模式运行,spigot.yml 设置 moved-too-quickly-multiplier: 100.0 防止因 RL 快速移动被踢。
  • State freshness / 状态新鲜度zmq.CONFLATE=1 on the SUB socket ensures only the latest game state is processed, dropping stale frames. / SUB socket 设置 zmq.CONFLATE=1,确保只处理最新的游戏状态,丢弃过时帧。
  • Yaw wrap-around / 偏航角回绕:Angular differences computed as (d + π) % 2π − π to handle the ±π boundary correctly. / 角度差计算为 (d + π) % 2π − π 以正确处理 ±π 边界。

Bugs fixed during development / 开发过程中修复的关键 Bug

# Bug Fix / 修复
1 Block ID used state ID (~26000+) instead of type ID Registries.BLOCK.getRawId() instead of getRawIdFromState() / 改用类型 ID
2 Pitch/Yaw sent in degrees instead of radians Multiply by Math.PI/180 on Java side / Java 侧乘以 Math.PI/180
3 N_BLOCK_TYPES too small (512) Raised to 1200 / 提升至 1200
4 view_delta computed across multi-file boundaries Compute per-file, then concat / 逐文件计算再拼接
5 Yaw wrap-around at ±π caused incorrect gradients (d+π) % 2π − π normalization / 角度归一化
6 Idle frames (no keypress) defaulted to action 0 Filter idle frames in convert_data.py / 过滤空闲帧
7 A/S key order swapped in BC unpacking W, S, A, D order (S before A) / S 在 A 前面
8 Fabric mod writer not flushed on shutdown Registered shutdown hook on instance, not static / 实例注册 shutdown hook

Memory & Hardware Requirements / 内存与硬件需求

Component / 组件 Memory / 内存
macOS + background / 系统后台 ~3.0 GB
Paper server / Paper 服务器 ~1.5 GB
Mineflayer + Node.js ~0.3 GB
PyTorch MPS (training) / PyTorch MPS(训练) ~1.0 GB
Policy network inference / 策略网络推理 < 0.2 GB
Total / 合计 ~6 GB

Comfortably fits in 16 GB unified memory, leaving ample headroom for future LLM slow-loop integration via API.

在 16 GB 统一内存中绰绰有余,为未来通过 API 接入 LLM 慢环预留了充足空间。


Future Work / 未来计划

  • LLM slow loop / LLM 慢环:Integrate Claude/GPT API for high-level intent reasoning ("help the player chop trees", "avoid the creeper"). / 接入 Claude/GPT API 实现高层意图推理("帮玩家砍树"、"避开苦力怕")。
  • More action diversity / 更多动作多样性:Add sneak, attack, use-item actions for richer interaction. / 添加潜行、攻击、使用物品动作以实现更丰富的交互。
  • Terrain generalization / 地形泛化:Train on procedurally varied terrains (caves, oceans, mountains). / 在程序生成的多样地形(洞穴、海洋、山地)上训练。
  • Multi-agent / 多智能体:Have multiple bots coordinate — one follows, one scouts ahead. / 多个 bot 协同——一个跟随,一个前方探路。

Repository / 代码仓库

公共仓库:会上传 vs 不应上传 / Public repo: in vs out

会上传(源码与模板) 不上传(.gitignore,仅本地)
agent/bridge/(含 package-lock.json)、fabric-mod/paper-plugin/ 源码 bridge/node_modules/.venv/
mr_server/ 下配置模板(server.propertiesspigot.ymlops.json 等) mr_server/world*libraries/cache/*.jarlogs/
data/recordings/.gitkeepmodels/.gitkeep data/recordings/*.jsonldataset.h5models/*.ptruns/
mr_server/plugins/bStats/config.yml.example mr_server/usercache.json(含玩家名与 UUID)、mr_server/plugins/bStats/config.yml(含 bStats serverUuid
脚本与文档 .env / .env.*.claude/settings.local.json、Gradle build/.gradle/

仓库内的 ops.json 仅保留训练用机器人 OP;真人游戏账号请在本地用 /op <名字> 或编辑 ops.json,勿把含好友游戏 ID 的 ops.json / usercache.json 提交到公共仓库。

克隆后需要本地准备:创建 Python venv 并安装依赖;cd bridge && npm install;将 Paper JAR 放入 mr_server/ 并首次启动生成世界;录制与权重放在 data/recordings/models/(上述目录默认不提交)。


License / 许可证

MIT License. See LICENSE for details.


Acknowledgements / 致谢

Built on: Mineflayer · Paper MC · Fabric · PyTorch · ZeroMQ · CleanRL

About

Embodied Minecraft companion research using behavioral cloning and PPO reinforcement learning on Apple Silicon.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages