Minecraft Forge Mod 开发手记——从零打造自定义物品
大约 4 分钟
概要
作为一个程序员兼 Minecraft 玩家,迟早会走到这一步——自己写 Mod。
本文记录了用 Minecraft Forge 1.20.6 开发一套自定义物品的过程:包括一个能探测钻石矿的探测器、一把带特效的美弓、一套终极盔甲,以及配套的成就系统和存档持久化。
不夸张地说,写 Minecraft Mod 是一种既能学 Java 又能玩得开心的学习方式。
环境搭建
Forge 1.20.6 使用 MDK(Mod Development Kit),Gradle 构建:
forge-1.20.6-50.2.0-mdk/
├── src/main/java/zzzz/fmltutor/ # Mod 源码
├── src/main/resources/ # 资源文件(模型、纹理、语言)
├── build.gradle # Gradle 构建配置
└── gradlew.bat # Windows 构建脚本
核心依赖只需要 Forge 本身,构建命令:
.\gradlew.bat build # 编译
.\gradlew.bat runClient # 启动测试客户端
Mod 主类
每个 Forge Mod 的入口是一个带 @Mod 注解的类:
@Mod("fmltutor")
public class FMLTutor {
public static final String MODID = "fmltutor";
public FMLTutor(FMLJavaModLoadingContext context) {
IEventBus modEventBus = context.getModEventBus();
// 注册物品
ModItems.ITEMS.register(modEventBus);
// 注册事件处理器
MinecraftForge.EVENT_BUS.register(new CraftingEventHandler());
}
}
三个关键步骤:
- 物品注册——告诉游戏"我有这些新物品"
- 事件监听——在游戏事件发生时执行自定义逻辑
- 创造模式标签——让物品出现在创造模式物品栏
钻石探测器:最有"程序员味"的物品
这是我的得意之作——一个可以探测附近钻石矿的工具:
public class DiamondDetector extends Item {
private static final double SUCCESS_CHANCE = 0.125; // 12.5% 成功率
private static final int SEARCH_RADIUS = 16; // 搜索半径
private static final int COOLDOWN_TICKS = 100; // 5秒冷却
@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
if (!level.isClientSide) {
if (Math.random() < SUCCESS_CHANCE) {
// 扫描 32×32×32 范围的所有方块
List<BlockPos> diamonds = findDiamondOre(level, player.blockPosition());
if (!diamonds.isEmpty()) {
// 找到!给出方向和距离
BlockPos nearest = findNearest(player.blockPosition(), diamonds);
int distance = (int) Math.sqrt(player.blockPosition().distSqr(nearest));
String direction = getDirection(player.blockPosition(), nearest);
player.sendSystemMessage(Component.literal(
"[Diamond Found!] " + direction +
" about " + distance + " blocks away, Y=" + nearest.getY()
));
}
}
}
}
}
这个物品的设计体现了几个游戏机制知识:
| 机制 | 实现 | 作用 |
|---|---|---|
| 概率 | 12.5% 成功率 | 不会太强也不会太弱 |
| 冷却 | CooldownTicks = 100 (5秒) | 防止无脑连点 |
| 耐久 | durability(16) | 限制使用次数 |
| 音效反馈 | 成功/失败不同音效 | 增强沉浸感 |
| 方向指示 | 计算东西南北+上下 | 功能性强 |
最核心的方块扫描算法就是三重循环遍历:
for (int x = -16; x <= 16; x++)
for (int y = -16; y <= 16; y++)
for (int z = -16; z <= 16; z++)
if (level.getBlockState(pos).is(Blocks.DIAMOND_ORE))
diamonds.add(pos);
朴实无华,但确实能跑。在 16 格半径内约 35000 个方块的扫描,服务端处理没有明显卡顿。
美丽弓:继承 + 增强
基于原版弓的增强版:
public class BeautifulBow extends BowItem {
public BeautifulBow() {
super(new Properties().durability(500)); // 原版 384
}
@Override
public AbstractArrow customArrow(AbstractArrow arrow) {
// 箭附带发光效果——方便追踪
arrow.addEffect(new MobEffectInstance(MobEffects.GLOWING, 200, 0));
// 伤害提升 50%
arrow.setBaseDamage(arrow.getBaseDamage() * 1.5);
return arrow;
}
@Override
public int getUseDuration(ItemStack stack) {
return 15; // 原版 20,更快的拉弓速度
}
}
对比原版弓:
| 属性 | 原版弓 | 美丽弓 |
|---|---|---|
| 耐久 | 384 | 500 |
| 伤害 | 1.0x | 1.5x |
| 拉弓速度 | 20 ticks | 15 ticks (快25%) |
| 特效 | 无 | 箭附带发光 |
合成成就系统
通过事件监听实现了"首次合成 Mod 物品时解锁成就":
@SubscribeEvent
public static void onItemCrafted(PlayerEvent.ItemCraftedEvent event) {
// 检查合成的物品是否属于本模组
if (craftedItem.getItem().getCreatorModId(craftedItem).equals("fmltutor")) {
if (!data.hasPlayerCrafted(playerUUID)) {
data.addPlayer(playerUUID); // 持久化保存
player.sendSystemMessage(Component.literal("恭喜!你解锁了答辩工艺!"));
}
}
}
关键是存档级别的持久化——使用 Minecraft 的 SavedData 机制:
public static class FmltutorCraftingData extends SavedData {
private final Set<UUID> playersWhoCrafted = new HashSet<>();
@Override
public CompoundTag save(CompoundTag tag) { /* 序列化为 NBT */ }
public static FmltutorCraftingData get(ServerLevel level) {
// 自动从存档加载或创建
return storage.computeIfAbsent(..., "fmltutor_crafting_data");
}
}
这样即使退出重进、切换世界,每个玩家的合成记录都会被保留。
终极盔甲套装
一套满级防护盔甲,四个部位(头盔、胸甲、护腿、靴子),通过 LivingHurtEvent 事件实现特殊伤害减免逻辑。
开发心得
- Forge 事件系统非常强大——几乎所有游戏行为都有对应的事件可以监听和修改
- 客户端/服务端分离是核心概念——很多逻辑只在服务端执行(
!level.isClientSide),忘记这个会导致各种奇怪 bug - 物品注册的时机很重要——必须在 Mod 构造期间通过
DeferredRegister注册,时机不对就不生效 - 模型和纹理需要 JSON 配置——
models/item/和textures/item/目录下的资源文件决定物品在游戏中的外观
小结
Minecraft Mod 开发是一个非常适合 Java 程序员的练手项目。它涉及的领域很广:
- 事件驱动架构
- 数据持久化(NBT)
- 客户端/服务端通信
- 资源管理和加载
- 3D 渲染管线
而且最棒的是——你写的每一行代码,都能在游戏里亲眼看到效果。这种即时反馈是其他开发体验难以比拟的。
完整源码见
D:\workspace\project\forge\,运行./gradlew.bat runClient即可体验。