NeoForge P1 - 了解基础

1046 字
5 分钟
NeoForge P1 - 了解基础

一、NeoForge 的本质#

实际上,它并不是一个工具,而是三层东西结合在一起的:

Terminal window
Java Mod 代码 -> NeoForge API 注册实体、监听事件、网络包等等 -> FML / ModLauncher 注入Minecraft

FML(Forge Mod Loader) 是底层,负责在 Minecraft 启动时扫描 neoforge.mods.toml,用 ModLauncher 把模组的类和资源注入 JVM。

NeoForge API 是中间层,提供你在代码里用的所有东西:@Mod、DeferredRegister、事件总线、IItemHandler、网络系统等等。

模组就是最上层:一个被 @Mod 注解的类,通过构造函数接收 IEventBus,然后往上面注册实体、物品、事件监听器。

二、核心概念即 「注册 + 事件」#

// 声明一个注册器,绑定到 ENTITY_TYPE 注册表
public static final DeferredRegister<EntityType<?>> ENTITIES =
DeferredRegister.create(Registries.ENTITY_TYPE, "mymod");
// 注册一个实体
public static final DeferredHolder<EntityType<?>, EntityType<MyEntity>> MY_ENTITY =
ENTITIES.register("my_entity",
() -> EntityType.Builder.of(MyEntity::new, MobCategory.CREATURE)
.sized(0.6f, 1.8f)
.build("mymod:my_entity"));
// 构造函数里挂到 MOD 总线
public MyMod(IEventBus modEventBus) {
ENTITIES.register(modEventBus);
}

DeferredRegister 是一个「延迟注册容器」——你在静态初始化时往里放东西,但真正写入 Registries 是在相应的注册事件触发时。不会出现注册顺序问题。

同理,物品、方块、创造模式标签页、粒子类型、附魔……全部走同一套 DeferredRegister 模式。

三、事件#

Minecraft 运行过程中会在特定时机「发事件」,模组「监听」事件来做自己的逻辑。NeoForge 有两条独立总线:

MOD 总线:

Terminal window
获取方式:构造函数参数 IEventBus modEventBus
注册阶段:实体属性、模型层、能力注册
典型事件为:EntityAttributeCreationEvent、RegisterCapabilitiesEvent

NeoForge 总线:

Terminal window
获取方式:NeoForge.EVENT_BUS
游戏运行阶段:生物生成、玩家交互、世界 Tick
典型事件为:LivingDeathEvent、PlayerInteractEvent、ServerTickEvent

四、官方文档#

NeoForge 相关文档链接:

Terminal window
主文档:https://docs.neoforged.net/
社区 Wiki:https://github.com/neoforged/neoforge/wiki
Javadoc:https://neoforged.net/javadoc/
学习项目(车万女仆 By.酒石酸菌):https://github.com/TartaricAcid/TouhouLittleMaid

五、解耦#

学习了dalao的开源项目,仔细发现它们的各个功能模块与注册都是解耦的。

在软件工程中,耦合(Coupling) 指的是两个模块之间的依赖程度。当两个模块紧密依赖时,修改其中一个往往会影响另一个,这种牵一发而动全身的关系就叫“高耦合”。

解耦(Decoupling) 就是通过某种方式降低这种依赖,让各个模块可以独立变化、独立理解、独立测试。

那么,在我们先前的代码开发中,不难发现把所有功能都集合在了 HelloWorld.java 中,把所有功能全部在此进行注册与功能实现,如果所有逻辑都写在 HelloWorld.java 里:主类、事件监听、注册逻辑……全部挤在一起。一旦要修改事件监听逻辑,就得打开这个庞大的文件,在众多代码中找到那一小块。

所以我们需要对项目进行重构,从开源学习项目中不难发现,dalao在软件包下将诸多功能模块分别置于不同软件包下,仅在主类里完成注册。

那么,就让我们开始吧。

5.1 分析项目结构#

解耦前:

Terminal window
com.helloworld/
- HelloWorld.java
- ModEvents.java

由于所有的注册都写在了 HelloWorld.java 中,这显然是不行的,所以即刻重构!

预计解耦后:

Terminal window
com.helloworld/
- HelloWorld.java
- com.helloworld.event/
- ModEvents.java
- com.helloworld.init/
- InitItems.java
- InitTab.java

仅在主类里进行注册操作,把所有的功能模块写在其它软件包下(如event写事件,init写注册逻辑等),那么就开始对先前的代码进行改进吧!

5.2 实现重构#

com.helloworld.HelloWorld
@Mod(HelloWorld.MODID)
public class HelloWorld {
public static final String MODID = "helloworld";
public HelloWorld(IEventBus modEventBus) {
// 注册物品
InitItems.register(modEventBus);
// 注册物品栏
InitTab.register(modEventBus);
}
}
com.helloworld.events.ModEvents
@EventBusSubscriber(modid = HelloWorld.MODID)
public class ModEvents {
@SubscribeEvent
public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
event.getEntity().sendSystemMessage(Component.literal("Hello World!"));
}
}
com.helloworld.inits.InitItems
public class InitItems {
public static final DeferredRegister<Item> ITEM =
DeferredRegister.create(Registries.ITEM, HelloWorld.MODID);
public static void register(IEventBus modEventBus) {
ITEM.register(modEventBus);
}
}
com.helloworld.inits.InitTab
public class InitTab {
public static final DeferredRegister<CreativeModeTab> CREATIVE_TABS =
DeferredRegister.create(Registries.CREATIVE_MODE_TAB, HelloWorld.MODID);
public static final DeferredHolder<CreativeModeTab, CreativeModeTab> EXAMPLE_TAB =
CREATIVE_TABS.register("example_tab", () -> CreativeModeTab.builder()
.title(Component.translatable("springtsuki.tab"))
.icon(() -> new ItemStack(Items.DIAMOND))
.displayItems((parameters, output) -> {
output.accept(Items.COBBLESTONE);
output.accept(Items.OAK_PLANKS);
})
.build());
public static void register(IEventBus modEventBus) {
CREATIVE_TABS.register(modEventBus);
}
}

这样,对先前的代解耦就完成了。每一个功能模块的尾部预留一个注册函数,便于主入口调用。而具体的功能则可以编写在各个模块之间,实现解耦。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
NeoForge P1 - 了解基础
https://springtsuki.xucjno.com/posts/springtsuki/notes/java/2026/810-1/
作者
SpringTsuki
发布于
2026-08-10
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
SpringTsuki
你好,我是浅月。
公告
浅月的开发小窝!欢迎你来到这里!
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
17
分类
8
标签
16
总字数
19,430
运行时长
0
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.13.5
文章许可
CC BY-NC-SA 4.0

文章目录