Forge Java · First custom item

做出你的第一件 Forge 自定义道具

使用指定的 Forge 1.20.1-47.4.20 MDK 和 IntelliJ IDEA,亲手完成“星辉水晶”:它有唯一 ID、中文名称、原创像素贴图、创造模式入口和合成配方,最后还能构建成可安装的 JAR。

Minecraft 1.20.1 Forge 47.4.20 JDK 17 IntelliJ IDEA 约 90–120 分钟

Mission · 最终要交付什么

不是只让代码“没有红线”,而是完成一条可验证的道具生产线。

自定义道具看起来很小,却正好覆盖 Forge 模组最重要的基础:版本配套、注册表、事件总线、命名空间、客户端资源和构建流程。学完后,你不只会复制一行 new Item,还会知道游戏为什么能找到它、为什么贴图必须放在固定路径、出现紫黑方块时应该查哪一个文件。

01 · ENVIRONMENT

搭好指定版本

让 Minecraft 1.20.1、Forge 47.4.20、ForgeGradle、JDK 17 和 IntelliJ 使用同一套工程配置。

02 · REGISTRY

注册真正的物品

DeferredRegisterRegistryObject 创建 teacherma_item:star_crystal

03 · RESOURCES

连接代码与资源

添加中英文翻译、物品模型 JSON、透明 PNG 贴图,并理解每一层路径对应的资源 ID。

04 · DELIVERY

运行、排错和发布

使用 runClient 验证 Mods 列表与游戏效果,再通过 build 得到可安装 JAR。

完成标准:开发客户端左下角显示 Forge 47.4.20;Mods 列表里出现 TeacherMa Item Tutorial;输入 /give @s teacherma_item:star_crystal 后,玩家手中出现星辉水晶;./gradlew.bat clean build 最终显示 BUILD SUCCESSFUL

Version lock · 先锁版本再写代码

本课只讲这一套组合;不要把 1.21、NeoForge 或旧 Forge 教程拼进来。

Minecraft 模组 API 会随游戏版本变化。同样叫“注册物品”,1.16、1.20.1、1.21 和 NeoForge 的导入路径、事件写法与资源格式都可能不同。本课完全依据 Forge 1.20.1-47.4.20 MDK 的实际模板编写,并已用 JDK 17 完整构建和启动。

组件本课版本负责什么检查位置
Minecraft Java1.20.1目标游戏与资源格式gradle.properties
Forge47.4.20加载器、事件与注册 APIforge_version
Forge MDK1.20.1-47.4.20Gradle 工程模板与示例源码压缩包文件名
JDK17(64 位)编译、运行 Gradle 与开发客户端java -version
IntelliJ IDEACommunity 2025.x编辑、Gradle 同步、运行和调试Help → About
Gradle由 MDK Wrapper 固定下载依赖、处理资源和构建 JARgradle/wrapper
为什么不是“当前最新版”?Forge 官网还会继续发布 1.20.1 的新构建,但你指定的是 47.4.20。学习项目必须固定版本,复现成功后再单独开分支升级。不要只改一处版本号并期待所有旧代码自动兼容。

先建立注册表思维

游戏不是通过 Java 变量名认识物品,而是通过唯一资源 ID。我们的 ID 是 teacherma_item:star_crystal:冒号前是模组命名空间 teacherma_item,冒号后是物品路径 star_crystal。翻译键、模型位置、贴图路径和命令都围绕这两个部分连接。

DeferredRegister

先收集“稍后要注册”的对象,等 Forge 到正确生命周期再统一注册。它能避免在注册表还没准备好时过早创建对象。

RegistryObject

保存一个安全引用。对象真正注册完成后,通过 STAR_CRYSTAL.get() 获取物品,而不是在任何地方再 new Item

MOD Event Bus

物品注册和创造模式物品栏构建属于模组加载生命周期,所以要连接到 context.getModEventBus()

客户端资源

Java 负责“它是什么”,JSON 和 PNG 负责“它叫什么、怎么显示”。代码编译成功不代表资源路径一定正确。

Setup · 准备 MDK 与 IntelliJ

把压缩包正确解到空目录,再用 JDK 17 导入 Gradle 工程。

1

安装 64 位 JDK 17

Forge 1.20.1 官方文档要求 JDK 17。安装后打开 PowerShell,分别执行下面两条命令;两条都应显示 17,而不是只有 java 有结果、javac 找不到。

PowerShell
java -version
javac -version
2

确认 MDK 文件

从 Forge 官方 Files 页面选择 Minecraft 1.20.1,在 All Versions 中找到 47.4.20,下载这一行的 Mdk,不是 Installer。官方列出的 MDK 校验值为:

forge-1.20.1-47.4.20-mdk.zip
MD5  F3F4C354CB2955DCA6580713442EE4B1
SHA1 AE89B7ADEC05802FB805C9345B509029C6952EBB

Windows 可用 Get-FileHash 文件路径 -Algorithm SHA1 检查。校验值不一致时重新下载,不要继续使用损坏文件。

3

解压到简单路径

新建一个空目录,例如 C:\Projects\teacherma-forge-item,把 ZIP 里的内容直接解到这里。打开目录后应该立即看到 build.gradlegradlew.batgradle.propertiessrc,不能再多套一层同名文件夹。

4

用 IntelliJ 打开工程根目录

选择 File → Open,点包含 build.gradle 的根目录。若 IntelliJ 询问是否信任项目,确认它来自你刚验证的 Forge 官方 MDK 后选择 Trust Project。第一次同步会下载 Forge、Minecraft 和映射文件,可能需要数分钟。

IntelliJ IDEA 打开的 teacherma-forge-item 根目录,左侧可见 build.gradle、gradle.properties、gradlew.bat、src 与 JDK 17
看目录是否正确:左侧根节点下面直接出现 Gradle 文件与 src。External Libraries 中能看到 ms-17,说明 JDK 17 已被 IntelliJ 识别。

设置 Project SDK = 17

Ctrl + Alt + Shift + S 打开 Project Structure,选择 Project。将 SDK 选为 JDK 17,Language level 选 17。JDK 名字可能叫 Temurin-17、ms-17 或 jdk-17,只要实际版本是 17 即可。

IntelliJ Project Structure 中 Project SDK 为 Microsoft OpenJDK 17.0.19,Language level 为 17
Project SDK 与 Language level 都是 17。截图中的 ms-17 是本机 JDK 的显示名称,不要求你安装同一个发行商。

设置 Gradle JVM = Project SDK 17

打开 Settings → Build, Execution, Deployment → Build Tools → Gradle,把 Gradle JVM 设为 Project SDK。这一项决定真正执行构建的 Java;只改 Project SDK、却让 Gradle 继续使用 21,仍可能遇到版本错误。

IntelliJ Gradle 设置中 Distribution 为 Wrapper,Gradle JVM 为 Project SDK ms-17
两处关键值:Distribution 保持 Wrapper;Gradle JVM 选择 Project SDK ms-17。点击 OK 后,在 Gradle 工具窗口执行 Reload All Gradle Projects。
第一次先做空工程测试:不要马上删除示例代码。先在根目录运行 ./gradlew.bat build。空 MDK 能构建成功,才说明网络、JDK 与 Gradle 基础环境正确;之后出错就更容易定位到自己的改动。

Identity · 给模组换成自己的身份

先改 gradle.properties,再创建与包名一致的 Java 目录。

打开根目录的 gradle.properties。Minecraft 与 Forge 版本保持 MDK 原值,只替换 Mod Properties 区域。mod_id 必须是小写英文、数字和下划线;不要写中文、空格或连字符。

gradle.properties · 只展示需要确认或修改的项目
minecraft_version=1.20.1
forge_version=47.4.20
mapping_channel=official
mapping_version=1.20.1

mod_id=teacherma_item
mod_name=TeacherMa Item Tutorial
mod_license=All Rights Reserved
mod_version=1.0.0
mod_group_id=de.teacherma.itemtutorial
mod_authors=Teacher Ma
mod_description=A small Forge 1.20.1 tutorial mod that adds the Star Crystal item.
字段本课值容易出错的地方
mod_idteacherma_item必须与 @Mod 常量和资源命名空间完全一致
mod_group_idde.teacherma.itemtutorial与 Java 顶部 package 和目录层级一致
mod_nameTeacherMa Item Tutorial这是 Mods 菜单显示名,可以有空格
mod_version1.0.0修改代码后是否升级由你决定,不等于 Forge 版本

删除示例 Java 包

MDK 原本带有 com.example.examplemod 包、ExampleMod.javaConfig.java。确认空模板已经构建成功后,可以删除这个示例包,再创建 de.teacherma.itemtutorial。不要保留两个带不同 @Mod ID 的入口,否则你会同时加载不需要的示例模组。

不要手改展开后的 mods.toml 版本:47.4.20 MDK 使用占位符,例如 ${mod_id}。Gradle 在 processResources 阶段把 gradle.properties 的值填进去。保持模板结构,只修改属性文件更不容易漏项。

File map · 先把所有文件放对位置

路径就是资源 ID 的一部分;一个字母错位都会让贴图或翻译失联。

src/main 下建立下面的结构。IntelliJ 中右键目录选择 New → Package 创建 Java 包;资源目录用 New → Directory。所有目录名均使用小写。

最终工程关键结构
teacherma-forge-item/
├─ build.gradle
├─ gradle.properties
├─ gradlew.bat
└─ src/main/
   ├─ java/de/teacherma/itemtutorial/
   │  ├─ TeacherMaItemMod.java
   │  └─ item/
   │     └─ ModItems.java
   └─ resources/
      ├─ META-INF/
      │  └─ mods.toml
      ├─ assets/teacherma_item/
      │  ├─ lang/
      │  │  ├─ en_us.json
      │  │  └─ zh_cn.json
      │  ├─ models/item/
      │  │  └─ star_crystal.json
      │  └─ textures/item/
      │     └─ star_crystal.png
      └─ data/teacherma_item/recipes/
         └─ star_crystal.json

assets 是显示资源

语言、模型、贴图主要由客户端读取。路径里的 teacherma_item 必须等于 mod_id

data 是游戏数据

配方、战利品表、标签等由数据包系统读取。配方文件也使用相同命名空间。

Java 包防止类冲突

de.teacherma.itemtutorial 应当换成你拥有或能保证唯一的包名,不要在正式项目继续使用 com.example

文件名决定路径部分

star_crystal.jsonstar_crystal.png 与注册名 star_crystal 保持同名,排错会简单很多。

Java · 注册道具并放进创造模式

分成两个类:入口类负责接线,ModItems 专门管理物品。

第一步:创建 ModItems.java

de.teacherma.itemtutorial.item 包中创建 ModItems。下面是本课完整代码,可以直接复制;先保证包名与自己的目录一致。

src/main/java/de/teacherma/itemtutorial/item/ModItems.java
package de.teacherma.itemtutorial.item;

import de.teacherma.itemtutorial.TeacherMaItemMod;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;

public final class ModItems {
    public static final DeferredRegister<Item> ITEMS =
            DeferredRegister.create(ForgeRegistries.ITEMS, TeacherMaItemMod.MOD_ID);

    public static final RegistryObject<Item> STAR_CRYSTAL = ITEMS.register(
            "star_crystal",
            () -> new Item(new Item.Properties()
                    .stacksTo(16)
                    .rarity(Rarity.UNCOMMON))
    );

    private ModItems() {
    }

    public static void register(IEventBus eventBus) {
        ITEMS.register(eventBus);
    }
}

注册表类型

ForgeRegistries.ITEMS 表示我们要注册的是物品。方块、实体、声音各有自己的注册表,不能混用。

最终资源 ID

MOD_IDteacherma_item,注册名是 star_crystal,合起来就是 teacherma_item:star_crystal

Supplier 延迟创建

() -> new Item(...) 不是立刻运行,而是把创建方法交给 Forge,在正确注册阶段调用。

道具属性

stacksTo(16) 限制一格最多 16 个;UNCOMMON 让名称使用稀有度颜色。两行都可继续修改。

IntelliJ IDEA 中完整显示 ModItems 类的 DeferredRegister、RegistryObject 和 star_crystal 注册代码
检查 IntelliJ:类名、导入和注册代码不应有红色波浪线。左侧 External Libraries 中能看到 JDK 17;底部包路径应结束于 item → ModItems

第二步:创建入口类 TeacherMaItemMod.java

入口类必须有 @Mod 注解。47.4.20 MDK 的构造函数接收 FMLJavaModLoadingContext context,直接从参数取得 MOD 事件总线。旧教程可能使用静态 get();本课跟随指定 MDK,不混用旧写法。

src/main/java/de/teacherma/itemtutorial/TeacherMaItemMod.java
package de.teacherma.itemtutorial;

import de.teacherma.itemtutorial.item.ModItems;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

@Mod(TeacherMaItemMod.MOD_ID)
public class TeacherMaItemMod {
    public static final String MOD_ID = "teacherma_item";

    public TeacherMaItemMod(FMLJavaModLoadingContext context) {
        IEventBus modEventBus = context.getModEventBus();

        ModItems.register(modEventBus);
        modEventBus.addListener(this::addCreativeTabItems);
    }

    private void addCreativeTabItems(BuildCreativeModeTabContentsEvent event) {
        if (event.getTabKey() == CreativeModeTabs.INGREDIENTS) {
            event.accept(ModItems.STAR_CRYSTAL);
        }
    }
}
为什么要写 ModItems.register(modEventBus)只声明 DeferredRegister 相当于填好报名表,还没有提交。把它注册到 MOD Event Bus,Forge 才会在物品注册阶段处理列表。漏掉这一行时,代码可能编译成功,但游戏完全不知道这个物品。

BuildCreativeModeTabContentsEvent 只负责把已经注册的物品显示在“原材料(Ingredients)”标签页。它不负责注册物品本身。命令依然可以用唯一 ID 取得道具。

Client resources · 名称、模型和贴图

Java 已经创造“对象”,现在让玩家真正看见和读懂它。

1. 中文与英文名称

assets/teacherma_item/lang 创建两个 JSON。物品翻译键规则是 item.命名空间.路径,因此本课必须写成 item.teacherma_item.star_crystal

zh_cn.json
{
  "item.teacherma_item.star_crystal": "星辉水晶"
}
en_us.json
{
  "item.teacherma_item.star_crystal": "Star Crystal"
}

2. 物品模型 JSON

assets/teacherma_item/models/item 创建 star_crystal.jsonminecraft:item/generated 是常见的平面物品模型;layer0 指向贴图资源,注意这里不写 .png

models/item/star_crystal.json
{
  "parent": "minecraft:item/generated",
  "textures": {
    "layer0": "teacherma_item:item/star_crystal"
  }
}

3. 放入透明 PNG 贴图

把道具图保存为 assets/teacherma_item/textures/item/star_crystal.png。本课示例使用 64×64 透明 PNG。16×16、32×32 或 64×64 都可以,但像素风贴图缩放时不要使用模糊插值;透明区域必须真的带 Alpha,不能只是黑色或白色背景。

IntelliJ IDEA 图片预览中显示 64×64 透明背景的星辉水晶像素贴图
IntelliJ 右上角显示 64x64 PNG (32-bit color),说明尺寸与透明通道都正确。底部面包屑完整显示 assets → teacherma_item → textures → item → star_crystal.png
代码或文件组合后的含义
MOD_ID + "star_crystal"teacherma_item:star_crystal
翻译键item.teacherma_item.star_crystal
模型文件assets/teacherma_item/models/item/star_crystal.json
模型中的 layer0teacherma_item:item/star_crystal
最终贴图assets/teacherma_item/textures/item/star_crystal.png
JSON 没有注释:不要在 JSON 中写 // 说明,也不要在最后一项后多写逗号。文件必须保存为 UTF-8。推荐用 IntelliJ 的 Reformat Code,让缩进和括号一眼可查。

Optional data · 添加一个可生存获得的配方

注册让物品“存在”,配方让它在生存模式中“可获得”。

这一步不是显示道具的必要条件,但能帮助你理解 data 目录。创建 data/teacherma_item/recipes/star_crystal.json,让四个紫水晶碎片包围一个荧石粉,合成一颗星辉水晶。

data/teacherma_item/recipes/star_crystal.json
{
  "type": "minecraft:crafting_shaped",
  "pattern": [
    " A ",
    "AGA",
    " A "
  ],
  "key": {
    "A": {
      "item": "minecraft:amethyst_shard"
    },
    "G": {
      "item": "minecraft:glowstone_dust"
    }
  },
  "result": {
    "item": "teacherma_item:star_crystal",
    "count": 1
  }
}
1.20.1 格式提醒:这里的 result.item 是 1.20.1 可用写法。不要从更新版本文档复制已经改变的配方结果结构。数据包格式是最容易被“新版教程”悄悄影响的部分之一。

Run & verify · 启动并逐项验收

第一次启动的目标不是“玩一会儿”,而是收集四个明确证据。

先保存所有文件,然后在 IntelliJ 右侧 Gradle 工具窗口找到 Tasks → fg_runs → runClient(不同 IDEA 版本分组名可能稍有不同)并双击。也可以在工程根目录的 Terminal 运行 Wrapper 命令:

Windows · 工程根目录
./gradlew.bat runClient
第一次会很慢:Gradle 需要下载游戏元数据、资源、Forge 用户开发依赖和映射。看到 Downloading 不等于卡死。不要在下载过程中强制关闭 IntelliJ;网络恢复后可重新运行同一任务。

证据 1:版本正确

Minecraft Forge 1.20.1 开发客户端主菜单,左下角显示 Forge 47.4.20、Minecraft 1.20.1 和 3 mods loaded
左下角必须能读到 Forge 47.4.20Minecraft 1.20.1 和已加载的模组数量。若版本不同,说明你启动了别的工程或普通启动器。

证据 2:Forge 找到了模组入口

在主菜单点击 Mods,再选择 TeacherMa Item Tutorial。右侧应显示版本 1.0.0、Mod ID teacherma_item、作者和描述。这些内容由 gradle.propertiesmods.toml 展开后提供。

Forge Mods 列表中选中 TeacherMa Item Tutorial,右侧显示 ModID teacherma_item、版本和描述
Mods 页面完整显示模组身份,说明 @Mod、Mod ID、资源处理和入口加载都已经通过。

证据 3:命令能取得注册物品

创建一个允许作弊的测试世界。按 T 打开聊天框,输入以下命令。输入到 teacherma_item: 时应出现自动补全;执行后玩家获得一颗星辉水晶。

游戏内命令
/give @s teacherma_item:star_crystal
Minecraft 1.20.1 Forge 开发世界中玩家手持自定义星辉水晶,快捷栏第一格显示同一贴图
最终效果:快捷栏和玩家手中都显示原创水晶贴图。若命令成功但画面是紫黑格子,注册已经成功,问题只在模型或贴图资源。

证据 4:创造模式原材料标签中可见

切换到创造模式,打开物品栏并进入 Ingredients(原材料)标签,或在搜索框输入 Star Crystal / 星辉水晶。能找到它,说明 BuildCreativeModeTabContentsEvent 也正确执行。

注册 ID

/give 自动补全并成功,证明注册表中存在 teacherma_item:star_crystal

翻译

中文语言下显示“星辉水晶”,而不是 item.teacherma_item.star_crystal

模型和贴图

手中与快捷栏都显示水晶图案,不是紫黑错误纹理。

物品属性

同一格最多堆叠 16 个,名称使用 Uncommon 稀有度颜色。

创造模式标签

Ingredients 标签能找到物品,证明标签事件判断与 accept 正确。

配方

四个紫水晶碎片加一个荧石粉能合成,证明 data 资源已载入。

Debug clinic · 按症状定位

一次只处理第一条根本错误,不要同时改 Java、JSON 和版本。

Gradle 报 Java 版本、toolchain 或 class file 错误

先查三处:PowerShell 的 java -version、Project SDK、Gradle JVM 都应指向 JDK 17。改完 Gradle JVM 后执行 Reload All Gradle Projects。不要因为电脑已有 JDK 21 就把本课 MDK 的 java.toolchain 改成 21。

net.minecraftforge... 全部变红或 Gradle 无法解析依赖

通常是 Gradle 同步没有完成、网络下载中断或错误地用“普通 Java 项目”打开了 src 子目录。重新用包含 build.gradle 的根目录打开,确认 Gradle JVM 17,点击 Reload。网络恢复后可运行 ./gradlew.bat --refresh-dependencies build

启动时提示 Failed to create mod instance

检查 @Mod(TeacherMaItemMod.MOD_ID)、常量 teacherma_itemgradle.propertiesmod_id 和 Java 包路径。还要确认构造函数是本 MDK 的 TeacherMaItemMod(FMLJavaModLoadingContext context),没有混入别的版本教程。

/give 找不到 teacherma_item:star_crystal

先确认 Mods 列表有当前模组,再检查入口构造函数是否调用 ModItems.register(modEventBus)。若只声明了 DeferredRegister 而没有连接事件总线,Java 会编译,但物品不会进入注册表。

物品存在,但显示紫黑错误贴图

注册代码已经成功,集中检查三个位置:模型文件是否为 assets/teacherma_item/models/item/star_crystal.jsonlayer0 是否为 teacherma_item:item/star_crystal;PNG 是否为 assets/teacherma_item/textures/item/star_crystal.png。Windows 隐藏扩展名时尤其要防止文件其实叫 star_crystal.png.png

物品名显示为 item.teacherma_item.star_crystal

这是翻译缺失,不是注册失败。检查当前游戏语言对应的文件是否存在,例如简体中文必须是小写 zh_cn.json;键名必须与注册 ID 一致;JSON 不能有尾逗号或注释,并保存为 UTF-8。

命令能获得物品,但创造模式标签没有

检查入口类是否监听 addCreativeTabItems,判断是否使用 CreativeModeTabs.INGREDIENTS,并调用 event.accept(ModItems.STAR_CRYSTAL)。这只影响标签展示,不影响注册表和 /give

日志很长,不知道看哪里

从控制台第一条红色 ERROR、第一个 Caused by 或 JSON 文件名开始读。后面几百行往往只是同一个根因造成的连锁失败。复制完整的第一段错误和它前后约 20 行,远比只截最后一屏有效。

推荐排错顺序:先执行 ./gradlew.bat build 判断编译与资源语法;再看 Mods 列表判断入口;再用 /give 判断注册;最后判断翻译、模型、贴图和配方。每一步都只测试一层。

Build & install · 构建可安装 JAR

开发客户端验证通过后,用 Wrapper 做一次干净构建。

先退出开发客户端,避免 Windows 锁定文件。在工程根目录运行:

PowerShell · 发布构建
./gradlew.bat clean build

成功后打开 build/libs,本课生成的安装文件是 teacherma_item-1.0.0.jar。如果还有带 -sources 的文件,它只用于查看源码,不放进普通客户端。

1

安装匹配的 Forge 客户端

普通游戏启动器需要 Minecraft 1.20.1 的 Forge 47.4.20。MDK 只用于开发,不等于已经给日常启动器安装 Forge。

2

找到 mods 目录

Windows 默认常见位置是 %appdata%\.minecraft\mods。不同启动器可以使用独立实例目录,以启动器显示的游戏路径为准。

3

只保留一个版本

teacherma_item-1.0.0.jar 放入 mods。同一个 Mod ID 不要同时放多个版本,否则 Forge 会拒绝启动。

4

先用测试世界

启动 Forge 47.4.20 配置,先检查 Mods 列表和新建测试世界。安装、升级或移除模组前备份重要存档。

下载本课完整可编译工程

包含 Forge 47.4.20 MDK Wrapper、两个 Java 类、翻译、模型、原创星辉水晶贴图和配方。下载后请仍然设置 JDK 17,并让 IntelliJ 完成 Gradle 同步。

Practice · 从照做变成会改

每次只改一个变量,预测结果,再运行验证。

LEVEL 1

修改堆叠数量

stacksTo(16) 改成 8。重新运行后用命令给予 16 个,观察物品栏如何分成两格。

LEVEL 2

创建第二件道具

注册 moon_shard,补齐翻译、模型和贴图。列出所有必须保持同名的位置。

LEVEL 3

自定义创造模式标签

阅读 Forge 1.20.1 Items 文档,注册自己的 CreativeModeTab,用星辉水晶作为图标。

五分钟自测

1. 为什么注册名只写 star_crystal,命令却写完整 ID?

DeferredRegister 创建时已经绑定命名空间 teacherma_item,注册方法只需提供路径部分。游戏和资源系统对外使用完整 ResourceLocationteacherma_item:star_crystal

2. 为什么不能直接保存一个全局 new Item(...)

可注册对象必须在 Forge 的注册生命周期中进入对应注册表。DeferredRegister 推迟创建并返回 RegistryObject 安全引用,避免过早初始化和未注册对象。

3. ModItems.register(modEventBus) 漏掉会怎样?

待注册列表没有接到 MOD Event Bus,Forge 不会处理它。代码可能编译,甚至入口模组能出现在 Mods 页面,但 /give 找不到自定义物品。

4. 命令成功但贴图紫黑,应该先改 Java 吗?

不应该。命令成功说明 Java 注册已完成。应检查模型 JSON 的路径、layer0 资源 ID、PNG 文件名和透明贴图位置。

5. 为什么 Project SDK 与 Gradle JVM 都要检查?

Project SDK 服务于编辑器分析,Gradle JVM 真正执行构建。两者可以指向不同 Java;只改一个会产生“编辑器看起来正常,Gradle 却失败”的情况。

术语卡

术语一句话解释
MDKForge 提供的 Mod Developer Kit,包含 Gradle 工程、Wrapper、配置与示例源码。
Mod ID模组的唯一小写标识,也是资源命名空间,例如 teacherma_item
Registry游戏把唯一资源 ID 映射到物品、方块、实体等对象的系统。
DeferredRegisterForge 推荐的延迟注册辅助类,在正确生命周期创建并注册对象。
RegistryObject注册对象的安全引用,在注册完成后通过 get() 取得实例。
Event Bus发布和接收生命周期或游戏事件的通道;本课使用 MOD Event Bus。
Wrapper工程自带的 gradlew.bat,确保使用项目规定的 Gradle 版本。

Official references · 官方资料

版本、注册方式和物品 API 均以 Forge 官方资料为基线。

Lesson complete

你已经完成了 Forge 模组最小但完整的一次闭环。

现在你手里不只是一个水晶图标,而是一套可复用的方法:固定版本、验证空工程、注册对象、连接资源、逐层验收、构建交付。下一次做食物、武器或工具时,仍然从唯一 ID 和注册流程出发,再逐步增加自定义类与行为。