一个现代化的 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 |