This is an old revision of the document!
数据生成入门
数据生成是 Fabric API 中的新模块,允许动态生成配方、语言文件、战利品表、进度以及几乎所有带有自定义提供器的一切。每次你修改生成数据的代码,你都会需要运行 gradle 任务 runDatagen
。
启用数据生成
启用数据生成 API 的方式是在使用 fabric template mod generator 创建项目时勾选 Data generation
框。
这样我们就已经创建了 gradle 任务 runDatagen,并且已经为 IDE 提供好了可以直接运行的配置,不需要使用终端。手动这么做也不会花费很长时间。
===== 手动启用数据生成 =====
首先打开你的项目根文件夹中的
build.gradle 文件,并在文件的某处添加以下内容:
<code groovy gradle.build [highlight_lines_extra=“5,6,7,8,9,10,11,12,13”]>
… (文件剩余部分)
sourceSets {
main {
resources {
srcDirs += [
'src/main/generated'
]
}
}
}
</code>
然后找到这个文件的
generateTags()loom
部分,添加以下内容:
<code groovy gradle.build [highlight_lines_extra=“9,10,11,12,13,14,15,16,17,18,19,20”]>
… (文件剩余部分)
loom {
… (已经存在的内容)
runs {
这会添加一个运行数据生成 API 的新 gradle 任务:“gradlew runDatagen”
datagen {
inherit server
name “Data Generation”
vmArg “-Dfabric-api.datagen”
vmArg “-Dfabric-api.datagen.output-dir=${file(“src/main/generated”)}”
vmArg “-Dfabric-api.datagen.modid=${modid}”
runDir “build/datagen”
}
}
}
… (文件剩余部分)
</code>
* 注意:在一些情况下,你可能需要将 inherit server
这一行更改为 inherit client
。
你可能注意到了,这里使用了变量 ${modid}
,这应该在 gradle.properties
文件中定义。检查其中是否存在,如果没有,你可以添加,就像这样:
<code properties>
.. (文件的剩余部分)
modid=你的模组的id
.. (文件的剩余部分)
</code>
然后,在项目中定义一个新的类 DataGeneration
并实现 DataGeneratorEntrypoint
:
* 其中的 onInitializeDataGenerator
方法会在我们前面创建的 Gradle 任务运行时调用。
<code java>
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
public class DataGeneration implements DataGeneratorEntrypoint {
@Override
public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
}
}
</code>
然后我们需要在 fabric.mod.json
文件中,告诉 Fabric 这个入口点:
<code javascript [highlight_lines_extra=“6,7,8”]>
{
…(文件的剩余部分)
“entrypoints”: {
“fabric-datagen”: [
“com.example.ExampleModDataGenerator”
],
“main”: [
“com.example.ExampleMod”
],
“client”: [
“com.example.ExampleModClient”
]
},
…(文件的剩余部分)
}
</code>
我们先看看我们现在已经有的内容是否正常第一次,或者是否有任何的错误,确认无误后继续。运行 runDatagenClient
任务。你可以让 IDE 为你做这个,或者只需要在你的项目的根目录中打开终端并输入:
<code batch Windows>
gradlew runDatagen
</code>
<code bash Linux>
./gradlew runDatagen
</code>
看看结果并确认没有错误。
* 你可以忽略:com.mojang.authlib.exceptions.InvalidCredentialsException: Status: 401
,如果出现了的话。这个错误是因为我们正在运行的 Minecraft 的调试版本不会验证我们的账户。
如果你遇到错误,那么缺少或者错误的东西应该会非常清楚,但如果你无法查明,你可能需要前往 Discord 或 QQ 群中寻求帮助。
src/main
中应该会有个叫做 generated
的新文件夹。目前它会是空的,但我们生成数据(例如进度)之后,这些文件就会被保存。
==== IDE 实现(可选) ====
由于我们不会总是开启终端,因此我们可以在 Intellij IDEA
中设置一个配置,通过下拉菜单运行命令。
首先打开运行/调试配置
菜单,要打开它,你可以打开“运行”按钮旁的下拉菜单,点击编辑配置..
选项,也可以连续按两次 Shift
并在弹出的窗口中输入 Edit Configuration
。
然后点击 '+'
按钮,搜索 gradle
并选择。
在 运行
输入框中,输入 runDatagen
。点击 确定
,然后你就可以直接运行配置而不需要打开终端了。
====== 添加提供器 ======
这里有一些概述,讲述如何添加提供器,关于每个提供器更加详细的信息,请阅读以下几个页面:
* 进度生成
* 战利品表生成
* 模型生成
* 标签生成
* 配方生成
* 语言文件生成
在这个例子中,我们会创建一个标签提供器,因为最容易理解。
首先,在你的 DataGeneration
类中,创建新的 private static class
并继承 FabricTagProvider<T>
:
如有需要,可以把这个类放到单独的文件中,不过我们建议放在数据生成入口点类中。
<code java>
private static class MyTagGenerator extends FabricTagProvider<Item> {
public MyTagGenerator(FabricDataGenerator dataGenerator) {
super(dataGenerator, Registries.ITEM); 1.19.2 之前的版本用 Registry.ITEM
}
@Override
protected void generateTags() {
}
}
</code>
作为示例,我们会在 中添加一些基本的标签:
<code java>
创建名为“smelly_items”的物品标签。
private static final TagKey<Item> SMELLY_ITEMS = TagKey.of(RegistryKeys.ITEM, new Identifier(“tutorial”, “smelly_items”));
@Override
protected void generateTags() {
创建一个 tag builder,我们添加粘液球、腐肉以及物品标签 minecraft:dirt 中的所有内容。
getOrCreateTagBuilder(SMELLY_ITEMS)
.add(Items.SLIME_BALL)
.add(Items.ROTTEN_FLESH)
.addOptionalTag(ItemTags.DIRT);
在“generated”文件夹中,会自动生成“assets/tutorial/tags/items/smelly_items.json”。
}
</code>
现在,我们需要在你的入口点类的
onInitializeDataGenerator
中的数据生成器中,注册这个提供器。
<code java>
public class DataGeneration implements DataGeneratorEntrypoint {
@Override
public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
fabricDataGenerator.addProvider(MyTagGenerator::new);
}
}
</code>
当我们运行 gradlew runDatagenClient
,我们将会看到生成的文件形式,物品标签 json 应该存在:
<file javascript smelly_items.json>
{
“replace”: false,
“values”: [
“minecraft:slime_ball”,
“minecraft:rotten_flesh”,
{
“id”: “#minecraft:dirt”,
“required”: false
}
]
}
</file>