一个现代化的 Minecraft 1.21.1 (NeoForge) 工厂自动化 Mod。用命名空间标签替代传统线缆,配合自定义脚本语言 FM2Lang 实现灵活的自动化控制。
ResourceHandler 统一接口操作,搬运逻辑支持模拟-执行两阶段安全传输手持 Label Tool,右键方块将其加入当前命名空间的标签组。例如将几个箱子标记为 input,将熔炉标记为 smelters:
右键箱子 A → [factory/input]
右键箱子 B → [factory/input]
右键熔炉 → [factory/smelters]
将脚本写入 Program Disk,磁盘同时绑定命名空间 factory:
every 20 ticks {
move("input", "smelters", "minecraft:iron_ore", 64)
}
将磁盘插入 Factory Manager 方块,管理器自动编译并执行脚本。上述脚本会每秒(20 ticks)从 input 标签的箱子中取出最多 64 个铁矿石,放入 smelters 标签的熔炉中。
// 变量声明
var batchSize = 32
const maxTransfer = 64
// 赋值
batchSize += 8
// 条件判断
if count("input") > 0 {
move("input", "output", "minecraft:diamond")
} else if count("input") == 0 {
log("input is empty")
} else {
log("unexpected state")
}
// 循环
var labels = ["chest_a", "chest_b", "chest_c"]
for lbl in labels {
var cnt = count(lbl)
log("%s has %d items", lbl, cnt)
}
// 逻辑运算 (支持短路求值)
if hasItem("input", "minecraft:iron_ingot") and freeSlots("output") > 0 {
move("input", "output", "minecraft:iron_ingot")
}
数据类型: number, string, bool (true/false), nil, list, map
字符串拼接: str + any 自动拼接为字符串
方法调用:
list.size() // list.size() 或 list.len()
str.upper() // 转大写
str.contains("x") // 包含检测
map.get("key") // map 字段访问
// 定时触发 -- 每 20 ticks (1秒) 执行一次
every 20 ticks {
move("input", "output")
}
// 定时触发 -- 每 5 秒执行一次
every 5 seconds {
log("heartbeat")
}
// 红石脉冲触发
on redstone {
move("chest", "dispenser", "minecraft:arrow", 64)
}
// 启动触发 -- 程序加载或重新编译时执行一次
on startup {
log("Factory Manager online")
var total = count("storage")
log("storage has %d items", total)
}
用于 move、take 等函数,按物品 ID 或 NBT 数据过滤:
// 按物品 ID 过滤
move("input", "output", filter { item == "minecraft:coal" })
// 按 NBT 过滤 (耐久低于 100 的物品)
move("input", "repair", filter { nbt.Damage < 100 })
// 多条件组合
take("input", filter { item == "minecraft:diamond_sword", nbt.Damage == 0 })
// 通配符匹配
move("input", "output", filter { item contains "minecraft:diamond" })
| 函数 | 说明 | 返回值 |
|---|---|---|
move(src, dst) | 从 src 搬运所有物品到 dst | {moved, skipped} |
move(src, dst, item) | 搬运指定物品 | {moved, skipped} |
move(src, dst, item, amount) | 搬运指定数量 | {moved, skipped} |
move(src, dst, filter{...}) | 按 filter 搬运 | {moved, skipped} |
take(src) | 从 src 取出物品暂存 | {taken} |
take(src, item, amount) | 取出指定物品和数量 | {taken} |
put(dst) | 将暂存物品放入 dst | {inserted} |
count(label) | 统计标签下所有物品数量 | number |
count(label, item) | 统计指定物品数量 | number |
hasItem(label, item) | 检查是否存在指定物品 | bool |
freeSlots(label) | 查询剩余空槽位数 | number |
items(label) | 获取所有槽位的物品 ID | list<string> |
| 函数 | 说明 | 返回值 |
|---|---|---|
moveFluid(src, dst) | 搬运所有流体 | {moved, skipped} |
moveFluid(src, dst, fluid) | 搬运指定流体 | {moved, skipped} |
moveFluid(src, dst, fluid, amount) | 搬运指定量 (mB) | {moved, skipped} |
countFluid(label) | 统计流体总量 (mB) | number |
hasFluid(label, fluid) | 检查是否存在指定流体 | bool |
fluidCapacity(label) | 查询总容量 (mB) | number |
fluids(label) | 获取所有槽位的流体 ID | list<string> |
| 函数 | 说明 | 返回值 |
|---|---|---|
moveEnergy(src, dst) | 传输所有能量 | {moved, skipped} |
moveEnergy(src, dst, amount) | 传输指定量 (FE) | {moved, skipped} |
countEnergy(label) | 统计存储能量 (FE) | number |
energyCapacity(label) | 查询总容量 (FE) | number |
chargeItem(energyLbl, itemLbl) | 为物品充电 | {charged} |
chargeItem(energyLbl, itemLbl, max) | 限制每 tick 充电量 | {charged} |
| 函数 | 说明 | 返回值 |
|---|---|---|
transfer(type, src, dst) | 通用资源搬运 | {moved, skipped} |
transfer(type, src, dst, id) | 搬运指定资源 | {moved, skipped} |
transfer(type, src, dst, id, amount) | 搬运指定量 | {moved, skipped} |
type 可选值: "item", "fluid", "energy"
| 函数 | 说明 | 返回值 |
|---|---|---|
namespace() | 获取当前命名空间名 | string |
labels() | 获取当前命名空间所有标签名 | list<string> |
| 函数 | 说明 |
|---|---|
log(fmt, ...args) | 输出日志 (支持 %s, %d 格式化) |
min(a, b) / max(a, b) | 最小值 / 最大值 |
abs(n) | 绝对值 |
floor(n) / ceil(n) / round(n) | 向下取整 / 向上取整 / 四舍五入 |
random(min, max) | 随机整数 (含两端) |
str(v) / num(v) / bool(v) | 类型转换 |
len(v) | 长度 (list/string/map) |
range(n) | 生成 [0, n) 的整数列表 |
contains(coll, val) | 包含检测 (list/string) |
| 方块 | 说明 |
|---|---|
| Factory Manager | 核心方块,插入 Program Disk 后自动编译并执行脚本,每 tick 调度触发器 |
| Buffer | 缓冲方块 (开发中) |
| 物品 | 说明 |
|---|---|
| Label Tool | 标签工具,右键方块将其加入当前 namespace/label 组,NBT 存储命名空间和标签信息 |
| Program Disk | 程序磁盘,NBT 存储脚本源码和命名空间引用,插入管理器后生效 |
Program Disk (脚本源码 + 命名空间)
|
v
ManagerBlockEntity.setDisk()
|
v
ProgramBuilder.build() -- 词法分析 -> 语法分析 -> AST 构建
|
v
ProgramRunner
|-- globalScope (var/const 跨 tick 持久化)
|-- timers[] (every N ticks/seconds)
|-- events[] (on redstone / on startup)
|
v (每 tick / 事件触发)
Interpreter.executeBlock()
|-- Scope 链 (局部变量)
|-- ExecutionContext (Level, namespace, 日志, PendingTransfer)
|-- StdLib 内置函数调用
|
v
ResourceHandler -> NeoForge Capability (IItemHandler / IFluidHandler / IEnergyStorage)
src/main/
├── antlr/fm2/FM2Lang.g4 # FM2Lang 脚本语言语法定义 (ANTLR4)
├── java/dev/factorymanager/fm2/
│ ├── FM2.java # Mod 入口点
│ ├── block/
│ │ ├── ManagerBlock.java # 管理器方块
│ │ └── BufferBlock.java # 缓冲方块 (开发中)
│ ├── blockentity/
│ │ └── ManagerBlockEntity.java # 管理器方块实体 (编译/执行/红石触发)
│ ├── item/
│ │ ├── LabelToolItem.java # 标签工具
│ │ └── DiskItem.java # 程序磁盘
│ ├── namespace/
│ │ └── NamespaceManager.java # 命名空间管理器 (SavedData)
│ ├── lang/
│ │ ├── ASTBuilder.java # ANTLR -> AST 转换
│ │ ├── ProgramBuilder.java # 编译入口 (源码 -> ProgramNode)
│ │ ├── ast/
│ │ │ ├── Node.java # AST 基类
│ │ │ ├── NodeVisitor.java # 访问者接口
│ │ │ ├── expr/ # 表达式节点
│ │ │ └── stmt/ # 语句节点 (if/for/every/on/var...)
│ │ ├── runtime/
│ │ │ ├── Interpreter.java # 树遍历解释器
│ │ │ ├── ProgramRunner.java # 触发器调度器
│ │ │ ├── ExecutionContext.java # MC 执行上下文
│ │ │ ├── FM2Value.java # 运行时值类型
│ │ │ ├── Scope.java # 作用域链
│ │ │ └── FM2RuntimeException.java # 运行时异常
│ │ └── stdlib/
│ │ ├── StdLib.java # 内置函数注册表
│ │ └── BuiltinFunction.java # 内置函数接口
│ ├── common/resource/
│ │ ├── ResourceHandler.java # 通用资源接口 <CAP>
│ │ ├── ItemResourceHandler.java # 物品处理器 (IItemHandler)
│ │ ├── FluidResourceHandler.java # 流体处理器 (IFluidHandler)
│ │ ├── EnergyResourceHandler.java # 能量处理器 (IEnergyStorage)
│ │ └── ResourceTransferHelper.java # 通用搬运逻辑
│ └── registry/
│ ├── FM2Blocks.java # 方块注册
│ ├── FM2BlockEntities.java # 方块实体注册
│ ├── FM2Items.java # 物品注册
│ ├── FM2CreativeTabs.java # 创造模式标签页
│ └── FM2MenuTypes.java # 菜单类型注册
└── resources/
├── META-INF/neoforge.mods.toml # Mod 描述文件
└── assets/fm2/lang/en_us.json # 英文语言文件
./gradlew build
构建产物位于 build/libs/。
| 组件 | 版本 |
|---|---|
| Minecraft | 1.21.1 |
| NeoForge | 21.1.x |
| Java | 21 |
| ANTLR4 | 4.13.2 |
| License | MIT |