资源
资源是游戏使用的外部文件,不属于代码。纹理是最常见的一种,但 Minecraft 生态中还有许多其他资源。所有资源都需要代码中的系统来使用,因此本节也会介绍使用这些资源的系统。
Minecraft 通常有两类资源:逻辑客户端使用的资源称为 assets,逻辑服务端使用的资源称为 data。前者主要是纹理、显示模型、译文和声音等表现信息;后者则包括战利品表、配方、世界生成信息等会影响玩法的内容。它们分别从资源包和数据包加载。NeoForge 为每个 Mod 生成内置资源包与数据包。
资源包和数据包通常都需要 pack.mcmeta 文件,但现代 NeoForge 会在运行时自动生成,因此不必自行处理。
如果不清楚某种文件的格式,可以参考原版资源。NeoForge 开发环境不仅包含原版代码,也包含原版资源。在 IntelliJ 的 External Resources 或 Eclipse 的 Project Libraries 中,可以找到名为 ng_dummy_ng.net.minecraft:client:client-extra:<minecraft_version> 的 Minecraft 资源,以及名为 ng_dummy_ng.net.neoforged:neoforge:<neoforge_version> 的 NeoForge 资源。
客户端资源
另见 Minecraft Wiki 的资源包条目。
assets,即客户端资源,是仅在客户端有意义的资源。它们从资源包加载,资源包有时也被称为纹理包(源于旧版资源包只能影响纹理)。资源包本质上是一个 assets 文件夹,其中每个子文件夹对应包所包含的一个命名空间。例如,ID 为 coolmod 的 Mod 所用资源包通常包含 coolmod 命名空间,也可以额外包含 minecraft 等其他命名空间。
NeoForge 会自动将所有 Mod 资源包汇总到 Mod resources 包中,位于资源包菜单“已选资源包”一侧的最下方。目前无法禁用该包。不过,上方资源包可以覆盖下方资源包定义的资源。这既允许资源包作者替换 Mod 资源,也允许 Mod 开发者按需覆盖 Minecraft 资源。
资源包可以包含模型、方块状态文件、纹理、声音、粒子定义与语言文件。
服务端数据
另见 Minecraft Wiki 的数据包条目。
data 指所有服务端资源,通过数据包(data pack 或 datapack)加载。与资源包类似,数据包由 pack.mcmeta 文件和名为 data 的根文件夹组成。data 下的每个子文件夹也对应一个命名空间。例如,ID 为 coolmod 的 Mod 所用数据包通常包含 coolmod 命名空间,也可以额外包含 minecraft 等命名空间。
创建世界时,NeoForge 会自动应用所有 Mod 数据包,目前无法禁用它们。但大多数数据文件可以被优先级更高的数据包覆盖,因此也可以通过替换为空文件来移除。额外数据包可放入世界的 datapacks 子文件夹,再通过 /datapack 命令启用或禁用。
说明 目前没有内置方式将一套自定义数据包应用到所有世界,不过有多种 Mod 可以实现这一点。
数据包可以包含影响以下内容的文件夹:
| 文件夹 | 内容 |
|---|---|
advancement |
进度 |
damage_type |
伤害类型 |
loot_table |
战利品表 |
recipe |
配方 |
tags |
标签 |
neoforge/data_maps |
数据映射 |
neoforge/loot_modifiers |
全局战利品修改器 |
dimension、dimension_type、structure、worldgen、neoforge/biome_modifier |
世界生成文件 |
此外,还可以包含与命令集成的系统所用文件夹。这些系统较少与 Mod 配合使用,但也值得了解:
| 文件夹 | 内容 |
|---|---|
chat_type |
聊天类型 |
function |
函数 |
item_modifier |
物品修改器 |
predicate |
谓词 |
pack.mcmeta
另见 Minecraft Wiki 的 pack.mcmeta(资源包)与 pack.mcmeta(数据包)条目。
pack.mcmeta 保存资源包或数据包的元数据。对 Mod 而言,NeoForge 会自动生成这个文件,因此不再需要手动提供。如果仍需自行创建,完整规范见上述 Minecraft Wiki 链接。
数据生成
数据生成,通常称为 datagen,是以编程方式生成 JSON 资源文件的机制,用来避免手写文件的繁琐过程和常见错误。这个名称略有误导性,因为它既适用于服务端数据,也适用于客户端资源。
数据生成通过 Data 运行配置执行,该配置会与 Client、Server 配置一起自动生成。Data 配置遵循 Mod 生命周期,直到注册表事件触发完毕,然后触发 GatherDataEvent。可在该事件中以数据提供器的形式注册待生成对象;之后程序将对象写入磁盘并结束进程。
所有数据提供器都实现 DataProvider 接口,通常需要重写一个方法。Minecraft 和 NeoForge 提供的主要数据生成器如下(链接文章包含辅助方法等更多信息):
| 类 | 方法 | 生成内容 | 端 | 说明 |
|---|---|---|---|---|
BlockStateProvider |
registerStatesAndModels() |
方块状态文件、方块模型 | 客户端 | |
ItemModelProvider |
registerModels() |
物品模型 | 客户端 | |
LanguageProvider |
addTranslations() |
译文 | 客户端 | 构造函数还需传入语言。 |
ParticleDescriptionProvider |
addDescriptions() |
粒子定义 | 客户端 | |
SoundDefinitionsProvider |
registerSounds() |
声音定义 | 客户端 | |
SpriteSourceProvider |
gather() |
精灵来源/图集 | 客户端 | |
AdvancementProvider |
generate() |
进度 | 服务端 | 应使用 NeoForge 版本,而非 Minecraft 版本。 |
LootTableProvider |
generate() |
战利品表 | 服务端 | 需要额外方法和类,详见链接文章。 |
RecipeProvider |
buildRecipes(RecipeOutput) |
配方 | 服务端 | |
TagsProvider 的各个子类 |
addTags(HolderLookup.Provider) |
标签 | 服务端 | 有多个专用子类,详见链接文章。 |
DataMapProvider |
gather() |
数据映射条目 | 服务端 | |
GlobalLootModifierProvider |
start() |
全局战利品修改器 | 服务端 | |
DatapackBuiltinEntriesProvider |
不适用 | 数据包内置条目,例如世界生成和伤害类型 | 服务端 | 不重写方法,而是在构造函数的 lambda 中添加条目,详见链接文章。 |
JsonCodecProvider(抽象类) |
gather() |
带有 codec 的对象 | 两端 | 可继承该类,用于任何具有数据编码 codec 的对象。 |
这些提供器遵循相同模式:先创建子类并添加待生成资源,再在事件处理器中将提供器添加到事件。以 RecipeProvider 为例:
public class MyRecipeProvider extends RecipeProvider {
public MyRecipeProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider) {
super(output, lookupProvider);
}
@Override
protected void buildRecipes(RecipeOutput output) {
// Register your recipes here.
}
}
// In some event handler class
@SubscribeEvent // on the mod event bus
public static void gatherData(GatherDataEvent event) {
// Data generators may require some of these as constructor parameters.
// See below for more details on each of these.
DataGenerator generator = event.getGenerator();
PackOutput output = generator.getPackOutput();
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
// Register the provider.
generator.addProvider(
// A boolean that determines whether the data should actually be generated.
// The event provides methods that determine this:
// event.includeClient(), event.includeServer(),
// event.includeDev() and event.includeReports().
// Since recipes are server data, we only run them in a server datagen.
event.includeServer(),
// Our provider.
new MyRecipeProvider(output, lookupProvider)
);
// Other data providers here.
}
该事件提供以下上下文:
event.getGenerator()返回用于注册提供器的DataGenerator。event.getPackOutput()返回PackOutput,某些提供器用它确定输出位置。event.getExistingFileHelper()返回ExistingFileHelper,供可能引用其他文件的提供器使用,例如能指定父模型的方块模型。event.getLookupProvider()返回CompletableFuture<HolderLookup.Provider>,主要供标签和数据生成注册表引用其他可能尚不存在的元素。event.includeClient()、event.includeServer()、event.includeDev()与event.includeReports()返回布尔值,可用于检查是否启用了下述特定命令行参数。
命令行参数
数据生成器接受以下命令行参数:
--mod examplemod:为指定 Mod 运行数据生成。NeoGradle 会自动为所属 Mod ID 添加;如果一个项目包含多个 Mod 等情况,可自行补充。--output path/to/folder:指定输出文件夹。建议使用 Gradle 的file(...).getAbsolutePath(),从相对于项目根目录的路径生成绝对路径。默认为file('src/generated/resources').getAbsolutePath()。--existing path/to/folder:检查现有文件时将指定文件夹纳入范围。同样建议使用 Gradle 的file(...).getAbsolutePath()。--existing-mod examplemod:检查现有文件时将指定 Mod JAR 中的资源纳入范围。- 生成器模式(均为布尔参数,不需要附加值):
--includeClient:是否生成客户端资源(assets),通过GatherDataEvent#includeClient()在运行时检查。--includeServer:是否生成服务端资源(data),通过GatherDataEvent#includeServer()检查。--includeDev:是否运行开发工具。Mod 通常不应使用此项,通过GatherDataEvent#includeDev()检查。--includeReports:是否导出已注册对象列表,通过GatherDataEvent#includeReports()检查。--all:启用所有生成器模式。
在 build.gradle 中添加以下内容,即可把参数加入运行配置:
runs {
// other run configurations here
data {
programArguments.addAll '--arg1', 'value1', '--arg2', 'value2', '--all' // boolean args have no value
}
}
例如,要复现默认参数,可以这样设置:
runs {
// other run configurations here
data {
programArguments.addAll '--mod', 'examplemod', // insert your own mod id
'--output', file('src/generated/resources').getAbsolutePath(),
'--includeClient',
'--includeServer'
}
}
来源: NeoForged/Documentation(1.21.1)。中文翻译依据提交
4a680cdd4d15。