103 lines
4.8 KiB
Markdown
103 lines
4.8 KiB
Markdown
---
|
||
front: https://nie.res.netease.com/r/pic/20211104/69055361-2e7a-452f-8b1a-f23e1262a03a.jpg
|
||
hard: 高级
|
||
time: 15分钟
|
||
---
|
||
|
||
# 了解自定义特征规则
|
||
|
||
在第六章中,我们已经初步学期了如何通过编辑器制作一个**特征规则**(**Feature Rule**,又译**地物规则**)。在本节中,我们将从JSON的层面更详细地了解特征规则。
|
||
|
||
## 了解特征规则文件
|
||
|
||
我们先来查看我们之前使用编辑器制作的那个特征规则的代码:
|
||
|
||
```json
|
||
{
|
||
"format_version": "1.14.0",
|
||
"minecraft:feature_rules": {
|
||
"description": {
|
||
"identifier": "tutorial_demo:demo_feature_rules",
|
||
"places_feature": "tutorial_demo:demo_feature"
|
||
},
|
||
"conditions": {
|
||
"placement_pass": "surface_pass"
|
||
},
|
||
"distribution": {
|
||
"coordinate_eval_order": "xzy",
|
||
"iterations": 1,
|
||
"scatter_chance": 10,
|
||
"x": {
|
||
"distribution": "uniform",
|
||
"extent": [
|
||
0,
|
||
16
|
||
]
|
||
},
|
||
"y": "query.get_height_at(variable.originx,variable.originz)-3",
|
||
"z": {
|
||
"distribution": "uniform",
|
||
"extent": [
|
||
0,
|
||
16
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
我们可以看到,特征规则是可以放在`netease_feature_rules`文件夹中的,使用的模式标识符皆为`minecraft:feature_rules`,并且在这里我们使用的是`1.14.0`的格式版本。事实上,我们也可以使用`1.13.0`和`1.16.0`的格式版本。
|
||
|
||
在模式标识符下有三个字段,分别是`description`、`conditions`和`distribution`,分别是该特征规则的描述、条件和分布。其中,我们可以看到分布对象`distribution`中的内容非常地熟悉。没错,这里和散植特征的格式是完全一致的。其实,每一个已定义的特征规则都会在游戏生成生物群系的不同阶段上**逐区块**地执行一次类似于散植特征的逻辑。简单地说,在每个区块上,特征规则都会随机选取一个点,然后以该点为起始点做一次散植,因此,我们可以在`distribution`对象中定义一套与散植特征相同格式的字段。唯一的不同是,散植特征中的`places_feature`字段在这里被移动到了描述对象`description`中。
|
||
|
||
条件对象`conditions`则用于定义特征规则放置特征的条件,其中`placement_pass`便是我们之前在第六章中便接触过的特征**放置阶段**(**Placement Pass**)的定义。这里我们使用了`surface_pass`来代表在生成器生成地形中的地表阶段放置。
|
||
|
||
在我们这个示例中,三个轴向的坐标的串演算顺序为`xzy`。同时,我们可以看到`y`字段中使用了获得X轴和Z轴起始点处的世界高度的Molang查询函数。如果Y轴先于X、Z轴演算,则我们无法通过变量得到X和Z轴的起始点坐标。那么我们目前的逻辑就会失效,这也是为什么我们将串演算顺序调整成了`xzy`的原因。
|
||
|
||
我们再来看一个原版特征规则的示例:
|
||
|
||
```json
|
||
{
|
||
"format_version": "1.13.0",
|
||
"minecraft:feature_rules": {
|
||
"description": {
|
||
"identifier": "minecraft:bamboo_jungle_after_surface_bamboo_feature",
|
||
"places_feature": "minecraft:bamboo_then_podzol_feature"
|
||
},
|
||
"conditions": {
|
||
"placement_pass": "after_surface_pass",
|
||
"minecraft:biome_filter": [
|
||
{
|
||
"test": "has_biome_tag",
|
||
"operator": "==",
|
||
"value": "bamboo"
|
||
},
|
||
{
|
||
"test": "has_biome_tag",
|
||
"operator": "==",
|
||
"value": "jungle"
|
||
}
|
||
]
|
||
},
|
||
"distribution": {
|
||
"iterations": "math.clamp(math.trunc(math.ceil((query.noise(math.trunc(variable.originx / 80), math.trunc(variable.originz / 80)) + 0.3) * 160)), 15, 160)",
|
||
"x": {
|
||
"distribution": "uniform",
|
||
"extent": [ 0, 16 ]
|
||
},
|
||
"y": "query.heightmap(variable.worldx, variable.worldz)",
|
||
"z": {
|
||
"distribution": "uniform",
|
||
"extent": [ 0, 16 ]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
这里我们可以看到,`conditions`字段下多了一个`minecraft:biome_filter`条件。这个条件是用于过滤生物群系的。通过一个或多个过滤器的线性排列或逻辑组合,我们可以使特征规则仅在特定的生物群系下放置特征,这实现了规则驱动的特征放置,这样放置出的特征也正是我们先前所说的**自动型特征**(**Automatic Feature**,又译**自动型地物**),即**隐式特征**(**Implicit Feature**,又译**隐式地物**)。
|
||
|
||
所以,从宏观上看,我们有两种放置特征的方式,一种是通过特征规则通过条件自动控制放置的隐式特征,另一种是通过生物群系的定义强制放置的显式特征。
|
||
|
||
至此,我们便基本学习了特征和特征规则的写法。接下来的几个小节,我们一起通过各种演示亲自操作,将各种特征的定义与生成的编写落到实处。 |