概述参考资料生物群系生物群系生成编写格式群系开发模板自定义spawn_rules自定义特征文件存放规则结构结构方块的获取&放置结构导出Netease Structure FeatureFeature Rules文件解读Feature Rules部分变量、函数解释placement_passvariable.originx与variable.originzvariable.worldx与variable.worldzcoordinate_eval_orderscatter_chancemath.modquery.is_biomequery.get_height_atquery.noiseNetease Structure Feature文件解读Netease Structure Feature放置规则Netease Structure Feature放置事件demo解释自定义维度自定义特征MOD卸载常见报错
概述
该功能仅在结构保存时需要开启实验性玩法。
开发者可以通过继承原版的生物群系,并修改其中的一些属性,从而控制自定义维度中的地貌及生物生成。
还可通过配置Netease Structure Feature和Feature Rules的方式,在地形生成时自动在区块上放置多个由结构方块导出的结构。
通过该方法定义的自定义维度不可以与“MirrorDimension”接口一起使用
下界和超平坦世界无法生成自定义特征
参考资料
- 生物群系的介绍:https://minecraft-zh.gamepedia.com/%E7%94%9F%E7%89%A9%E7%BE%A4%E7%B3%BB
- 官方wiki上的自定义生物群系json格式及说明:https://minecraft.gamepedia.com/Bedrock_Edition_beta_biomes_documentation
- 原版生物群系的json:见“Mod PC开发包”的
data/definitions/biomes
目录 - 官方wiki上的Features及Feature Rules文档: https://minecraft.gamepedia.com/Bedrock_Edition_features_documentation
- 原版features的json:见“Mod PC开发包”的
data/definitions/features
目录 - 原版feature rules的json:见“Mod
PC开发包”的
data/definitions/feature_rules
目录
生物群系
生物群系生成
目前基岩版生物群系生成的管线还处于硬编码的阶段,为了让开发者对配置自定义群系有一个基本的思路,先简单描述一下生物群系生成的各个步骤。如果有兴趣或者想有更深入的了解可以参考java版的源码以及网上的一些解析。
-
术语介绍
- 陆地生物群系:表面被实心方块覆盖的群系。
- 海洋生物群系:表面被水覆盖的群系。json中会带有“ocean”的标签(例如ocean.json)
- 深海生物群系:json中会带有“deep”的标签(例如deep_ocean.json)
- 基础生物群系:第一阶段生成的群系,后续会分化为其他变种。例如陆地的有丛林,森林,沙漠,平原等,海洋的有海洋,深海。json中“minecraft:world_generation_rules”下会带有“generate_for_climates”的键值(例如plains.json)
- 山地生物群系:指以下生成山地阶段中可以转化成的群系。即json中"hills_transformation"的值。
例如在plains.json中
"minecraft:world_generation_rules": {
"hills_transformation": [
[ "forest_hills", 1 ],
[ "forest", 2 ]
],
},
则forest及forest_hills为plains的山地群系变种。
-
突变生物群系:指以下生成山地阶段中,有较低概率会转化成的变种。即json中"mutate_transformation"的值。并且对应群系的json中会有"mutated"的标签。
例如在jungle.json中
xxxxxxxxxx
"minecraft:world_generation_rules": {
"mutate_transformation": "jungle_mutated",
},
则jungle_mutated为jungle的突变群系。
-
河流生物群系:
主要指river及frozen_river。在生成河流时,ice_plains会变成frozen_river,其他群系变成river。
-
海岸生物群系:
陆地群系与海洋群系相邻时,相邻处会生成的过渡群系。json中一般会带有shore或者beach的标签。
-
群系生成流程
-
将地图划分为海洋及陆地,并决定不同地区的温度。
温度类型包括:
frozen, cold, medium, lukewarm, warm
-
将海洋部分变为ocean,然后将部分ocean变为deep_ocean
-
将陆地的部分根据温度分化为基础陆地群系
-
一些硬编码的生成:
-
添加蘑菇岛群系
因此所有情况下都会有mushroom_island及mushroom_island_shore生成
-
将一些热带雨林群系变异为竹林
因此如果jungle被允许生成,那么bamboo_jungle也会生成
-
将一些平原变异为向日葵平原
因此如果plains被允许生成,那么sunflower_plains也会生成
-
-
进行山地及突变变异(根据json中配置的hills_transformation及mutate_transformation)
-
进行河流变异(硬编码)
-
进行海岸变异(硬编码)
-
将海洋的部分根据温度分化为基础海洋群系
-
编写格式
-
在行为包中新建一个netease_biomes文件夹。
-
为每个需要自定义生物群系的自定义维度创建一个以维度命名的文件夹。
关于自定义维度:
- 每个维度对应一个id,原生维度中主世界为0,地狱为1,末地为2。自定义维度的id从3开始,一直到20。
- 自定义维度的名称为"dm"前缀加数字id。如id为3的维度,命名为“dm3”。
-
在文件夹中编写需要重写的生物群系。对每个自定义群系,命名为原版群系加上维度名字及下划线为前缀。例如dm3维度的desert群系命名为"dm3_desert"。
对每个自定义群系,必须继承一个原版的生物群系,在description中用inherits表示,新群系的identifier需要与文件名相同。例如dm3维度重写desert群系,则需要编写一个dm3_desert.json:
xxxxxxxxxx
{
"format_version": "1.13.0",
"minecraft:biome": {
"description": {
"identifier": "dm3_desert",
"inherits": "desert"
},
"components": {
}
}
}
对每个自定义维度,每个原版群系都会有一个对应了继承他的自定义群系。在生成群系时,流程不会改变,但是生成时取到的是当前维度中继承后的群系。
-
在新群系中重写属性来覆盖原版群系的属性。
没有进行重写的属性会使用原版群系的属性。
没有进行重写的群系,会自动生成一个所有属性与原版群系相同的,带维度名称前缀的群系
-
目前支持的原版biomes json的字段包括:
-
minecraft:overworld_height
-
minecraft:overworld_surface
- 不支持带有block entity的方块,也不支持门,床等占多个位置的方块
-
可使用nbt设置带有auxvalue的方块。目前仅支持设置特殊沙子及特殊泥土类型。可参考原版群系的
mesa_plateau_stone.json
以及savanna_mutated
-
minecraft:world_generation_rules
-
-
自定义tag
所有的hills_transformation,mutate_transformation,值必须为当前维度的群系。
若原版群系带有这两个transformation,都需要重写为当前维度的群系。
例如原版desert群系,hills_transformation为desert_hills,mutate_transformation为desert_mutated,那么在自定义维度中,保持原有规则需要重写为
xxxxxxxxxx
{
"format_version": "1.13.0",
"minecraft:biome": {
"description": {
"identifier": "dm3_desert",
"inherits": "desert"
},
"components":{
"minecraft:world_generation_rules": {
"hills_transformation": "dm3_desert_hills",
"mutate_transformation": "dm3_desert_mutated"
}
}
}
}
如果想要删除群系的hills_transformation,mutate_transformation,generate_for_climates属性,可以参考以下方法:
xxxxxxxxxx
{
"format_version": "1.13.0",
"minecraft:biome": {
"description": {
"identifier": "dm4_ice_plains",
"inherits": "ice_plains"
},
"components": {
"minecraft:world_generation_rules": {
"hills_transformation": "dm4_ice_plains", //若设置为自己,则不会变异为其他群系
"mutate_transformation": "dm4_ice_plains", //若设置为自己,则不会变异为其他群系
"generate_for_climates": [
["frozen", 0] //若权重设置为0,则不会生成
]
}
}
}
}
需要注意,修改后的维度,陆地(不含ocean的tag)、海洋(含ocean的tag,但没有deep的tag)、深海(同时包含ocean及deep的tag)三种类型,每种类型的五种温度必须至少有1点权重
-
-
在新群系中添加新的标签,可用于spawn_rules等其他功能。
在“群系开发模板中”,默认给所有自定义维度添加了一个与维度名称一样的标签,便于开发。
开发者可以按需添加其他标签。
xxxxxxxxxx
{
"format_version": "1.13.0",
"minecraft:biome": {
"description": {
"identifier": "dm4_ice_plains",
"inherits": "ice_plains"
},
"components": {
"dm4": {}, //群系开发模板自动添加的标签
"my_dm4_tag": {} //添加其他自定义标签
}
}
}
群系开发模板
CustomBiomesMod中的tools\template
中提供了模板工具生成符合编写格式最低要求的自定义维度。生成的自定义群系有以下特征:
- 对两种transformation都进行了对应当前维度群系的重写
- 保留了原有generate_for_climates的字段
- 给每个群系添加了与维度名相同的标签
- 对每个自定义群系,都可以找到一个与之对应的去掉维度名称前缀的原版群系(见参考资料3)
开发者在编写自己的维度时,可以以此为模板进行开发。
使用方法:
- 在
CustomBiomesMod\customBiomesBehaviorPack\tools
目录打开命令行,输入
xxxxxxxxxx
python .\remake.py [维度名称]
维度名称为自定义维度的名称,例如要更改dm6自定义维度的群系,则输入
xxxxxxxxxx
python .\remake.py dm6
然后tools文件夹下会生成一个维度命名的文件夹。
- 将生成的文件夹拷贝到您的mod的netease_biomes下
- 前面完成了“编写格式”2-4步中编写一个合法自定义维度的最低要求。开发者可以在此基础上进行开发,修改群系的components。
自定义spawn_rules
1.在addon的bevavior目录下新增spawn_rules文件夹
2.创建一个json文件并命名,如example.json,例子:
xxxxxxxxxx
{
"format_version": "1.8.0",
"minecraft:spawn_rules": {
"description": {
"identifier": "minecraft:netease_example",
"population_control": "ambient"
},
"conditions": [
{
"minecraft:spawns_underground": {},
"minecraft:brightness_filter": {
"min": 0,
"max": 4,
"adjust_for_weather": true
},
"minecraft:height_filter": {
"min": 0,
"max": 63
},
"minecraft:weight": {
"default": 10
},
"minecraft:herd": {
"min_size": 2,
"max_size": 2
},
"minecraft:density_limit": {
"surface": 5
},
"minecraft:biome_filter": {
"test": "has_biome_tag", "operator":"==", "value": "animal"
}
}
]
}
}
3.在minecraft:spawn_rules里必须存在description
和conditions
所有的Spawn Rules必须存在一个Id,格式也是namespace:name,填写在identifier
中,注意该值的唯一性
description
中还有一个population_control
,
4.population_control
种类,每一种类都有生成个数的限制,该值可以为以下类型:
类型 |
---|
animal |
monster |
water_animal |
villager |
ambient |
cat |
pillager |
5.生成条件condition
可做如下设置:
Name | Description |
---|---|
minecraft:spawns_on_surface | 允许mob在地上生成 |
minecraft:spawns_underwater | 允许mob在水里生成 |
minecraft:brightness_filter | 允许mob生成的光照条件 |
minecraft:weight | mob生成的权重,默认为0 |
minecraft:difficulty_filter | mob生成的困难模式 |
minecraft:herd | herd的大小 |
minecraft:biome_filter | 允许mob生成的biome |
自定义特征
文件存放规则
自定义特征相关文件存放规则如下:
- Feature Rules文件应存放在行为包的 netease_feature_rules 目录下
- Netease Structure Feature文件应存放在行为包的 netease_features 目录下
- 结构文件应存放在行为包的 structures/开发者自定文件夹 目录下
微软的Feature及Feature Rules文件若放置在netease_features及netease_feature_rules目录下可在非实验性玩法下加载
结构
结构的编辑和导出需要玩家处于创造模式下,并开启实验性玩法。
结构方块的获取&放置
可通过指令/give @p structure_block获取结构方块。
结构方块放置后,可在世界中看到结构的白色轮廓。使用结构方块可打开其GUI,可在GUI中编辑结构的大小、距离结构方块的偏移。
结构中红、蓝、绿三线交汇点为该结构方块的坐标最小点,结构的放置都是从该点所在方块开始的。
若不希望结构中的空气方块在放置时覆盖掉其他方块,可通过指令/give @p structure_void获取结构空位,并放置在相应的空气方块上。
结构导出
Netease Structure Feature支持的单个结构最大尺寸为16 * 255 * 16,若超过最大尺寸,超出范围的方块可能不会成功放置;若方块在世界中的高度超过255也不会成功放置,建议结构高度不要设置过高。
通过Netease Structure Feature放置的结构不支持包含实体功能,即使结构中保存了实体,也不会生成。
结构名称应命名为 文件夹名:结构名,文件夹名由开发者自定,用于放置结构文件。需要注意的是行为包的 structures目录与结构文件之间必须有且仅有一层中间目录,即结构文件路径应为 行为包/文件夹1/结构文件 ,而不应为 行为包/文件夹1/文件夹2/结构文件 或其他。
在结构方块GUI界面模式选择"保存",点击导出即可导出该结构了。
若结构中包含火方块,通过NeteaseStructureFeature放置的火与永恒之火相似,不会熄灭、不会扩散,但依旧有燃烧伤害
Netease Structure Feature
Feature Rules文件解读
Feature Rules编写例子可参考官方文档。
xxxxxxxxxx
{
"format_version": "1.13.0",
"minecraft:feature_rules": {
"description": {
"identifier": "overworld_pumpkins_feature", // 自行设定的Feature Rules名称
"places_feature": "netease_pumpkins_structure_feature" // 该Feature Rules所放置的feature文件名称
},
"conditions": { // 设置Feature生成条件
"placement_pass": "surface_pass",
"minecraft:biome_filter": [ // 设置Feature会在哪些生物群系中生成
{
"all_of": [
{
"any_of": [
{
"test": "has_biome_tag",
"operator": "==",
"value": "dm4" // 自定义维度4
},
{
"test": "has_biome_tag",
"operator": "==",
"value": "dm5" // 自定义维度5
},
{
"test": "has_biome_tag",
"operator": "==",
"value": "the_end" // 末地
}
]
}
]
}
]
},
"distribution": { // Featuer放置规则
"iterations": "(math.mod(variable.originx,96)==48 || math.mod(variable.originx,96)==-48) && (math.mod(variable.originz,96)==48 || math.mod(variable.originz,96)==-48) && query.is_biome(variable.originx - 32, variable.originz - 32, 0, 1, 2, 9, 12, 46)?3:0", // 迭代放置次数,本句含义为X、Z方向每隔96个方块(6个区块)且尝试放置三次。variable.originx为准备放置feature的区块内最小的x坐标,variable.originz同理
"coordinate_eval_order": "xzy", // 放置Feature的坐标决定顺序,下文最终y坐标与x、z坐标存在依赖,故顺序为xzy
"scatter_chance": 100.0, // 放置Featuer概率,应满足0 < scatter_chance ≤ 100
"x": {
"distribution": "uniform", // 在一定范围内随机选取一个整数值
"extent": [ 0, 16 ] // 选取范围,不包括最大值,建议偏移范围不要超过[-16, 16],否则结构可能无法完整放置
},
"y": "query.get_height_at(variable.worldx, variable.worldz)", // variable.worldx为最终放置feature的x坐标,variable.worldz同理
"z": {
"distribution": "uniform",
"extent": [ 0, 16 ]
}
}
}
}
Feature Rules部分变量、函数解释
placement_pass
-
描述
placement_pass用于控制该feature在地形生成的哪个步骤时才生成。地形生成步骤可见官方wiki,里面有提及first_pass、before_underground_pass、underground_pass等。
variable.originx与variable.originz
-
描述
variable.originx为尝试放置该feature的区块的最小x坐标,variable.originz为尝试放置该feature的区块的最小z坐标。
variable.worldx与variable.worldz
-
描述
variable.worldx为经过计算后最终放置该feature的x坐标,variable.worldz为经过计算后最终放置该feature的z坐标。若Feature Rules中distribution填写如下:
xxxxxxxxxx
"distribution": {
"iterations": "1",
"coordinate_eval_order": "xzy",
"scatter_chance": 100.0,
"x": {
"distribution": "uniform", // 在一定范围内随机选取一个整数值
"extent": [ 0, 16 ] // 选取范围,不包括最大值,建议偏移范围不要超过[-16, 16],否则结构可能无法完整放置
},
"y": "query.get_height_at(variable.worldx, variable.worldz)",
"z": 6 // z轴偏移固定为6
}
则对于该feature而言:
variable.worldx = variable.originx + random.randint(0, 16)
variable.worldz = variable.originz + 6
coordinate_eval_order
-
描述
该项决定了放置feature时坐标的计算顺序,支持xyz、xzy、yxz、yzx、zxy、zyx。当Feature Rules中没有该项时,计算顺序默认为xzy。
scatter_chance
-
描述
scatter_chance用于控制该feature生成的概率百分比,传入值应大于0且小于等于100。
需要注意的是,对于多个小结构拼成的大型结构,若它们的scatter_chance不为100,会导致整个大型结构随机缺失某几块结构。若要控制大型结构的整体概率生成,应使用query.noise。
math.mod
-
描述
两数求余,需要注意的是取余结果的符号与被除数相同,如:
math.mod(7, 3) = 1 math.mod(7, -3) = 1
math.mod(-7, 3) = -2 math.mod(-7, -3) = -2
建议将除数设为正数,并将形如(math.mod(variable.originz,96) == 16 || math.mod(variable.originz,96) == -80) 的语句写成(math.mod(math.mod(variable.originz,96) + 96, 96) == 16 的形式。
query.is_biome
-
描述
判断在x、z坐标上的生物群系是否为目标生物群系,可传入当前区块之外的坐标
-
参数
参数名 | 数据类型 | 说明 |
---|---|---|
x | int | x世界坐标 |
z | int | z世界坐标 |
biomes | Args... | 生物群系的枚举值int,可参照3-3 minecraft枚举值文档中BiomeType项 |
query.get_height_at
-
描述
根据x、z坐标获取其上最高非空气方块的高度,可传入当前区块之外的坐标
-
参数
参数名 | 数据类型 | 说明 |
---|---|---|
x | int | x世界坐标 |
z | int | z世界坐标 |
query.noise
-
描述
用于产生伪随机数,传入两个数,返回一个 -1~1 之间的浮点数。当传入的两个参数相同时,query.noise得到的结果也相同。
可用于控制由多个结构组成的大型结构的概率生成。
-
参数
参数名 | 参数类型 | 说明 |
---|---|---|
num1 | float | 传入参数一 |
num2 | float | 传入参数二 |
-
举例
一个大型结构由两个小结构A、B组成,整个结构在X轴方向上每隔32个方块、在Z轴方向上每隔48个方块会生成一次,见下图:
若要控制整个结构以30%的概率生成,应在A与B的FeatureRule中使用query.noise函数,保证同一大型结构中的子结构传入的两参数相同,得到的输出相同,即可保证它们一同生成。
下面以图中绿色菱形点(B所在区块坐标最小点)的坐标作为query.noise的输入为例,A的Feature Rule中distribution应写成如下格式:
xxxxxxxxxx
"distribution": {
"iterations": "(math.mod(variable.originx,32)==0 && math.mod(variable.originz,48)==0 && math.abs(query.noise(variable.originx, variable.originz+16))<0.3)?1:0", // 由于query.noise范围在-1~1之间,因此使用了math.abs取绝对值再判断概率。且B所在区块坐标最小点的z坐标与A的variable.originz相距16,因此参数二为variable.originz+16
"coordinate_eval_order": "xzy",
"scatter_chance": 100.0, // 若要保证AB一同生成,则scatter_chance应为100
"x": 0,
"y": "query.get_height_at(variable.worldx, variable.worldz)",
"z": 0
}
而B的distribution应如下:
xxxxxxxxxx
"distribution": {
"iterations": "math.mod(variable.originx,32)==0 && (math.mod(math.mod(variable.originz,48)+48,48)==16 && math.abs(query.noise(variable.originx, variable.originz))<0.3)?1:0", // B所在区块坐标最小点的即为参照点,因此参数二为variable.originz
"coordinate_eval_order": "xzy",
"scatter_chance": 100.0, // 若要保证AB一同生成,则scatter_chance应为100
"x": 0,
"y": "query.get_height_at(variable.worldx, variable.worldz)",
"z": 0
}
理论上参照点可以选取任意一点,只要保证同一大型结构中A、B的query.noise传入的参数完全相同即可。
Netease Structure Feature文件解读
Netease Structure Feature格式如下:
xxxxxxxxxx
{
"format_version": "1.13.0",
"netease:structure_feature": { // feature类型必须为netease:structure_feature
"description": {
"identifier": "netease_pumpkins_structure_feature" // 自行设定的feature名称
},
"places_structure": "test:pumpkins" // 放置的结构名称,格式为 文件夹名:文件名
}
}
Netease Structure Feature放置规则
生成地形时,当区块加载完后,才会尝试在该区块放置Netease Structure Feature。Feature Rules文件中distribution里的坐标决定了结构中坐标最小方块的放置位置,若结构过大,可能会有部分方块落在未加载的区块中,这些方块将无法成功放置在世界中。
若要使Netease Structure Feature自动生成 16 * 合法高度 * 16 的结构,需要将Feature Rules中的x和z均设为0,才能保证结构会被完全加载。
若目标结构尺寸超过最大尺寸,可将其分割成多个16 * 合法高度 * 16的结构,通过配置多个Feature Rule使它们在相邻区块上生成,可参考CustomBiomesMod中的羊毛Feature Rule。
Netease Structure Feature放置事件
通过Netease Structure Feature放置结构的事件为PlaceNeteaseStructureFeatureEvent,可通过服务端feature组件添加、移除对某个结构的监听,详见 3-1 MOD SDK文档。
需要注意的是,在PlaceNeteaseStructureFeatureEvent监听事件中,由于该事件较为特殊,仅能进行是否取消放置该结构的设置,此时若调用其他mod SDK接口将不会生效。
demo解释
请对照示例中的CustomBiomesMod阅读
该demo定义了3个自定义维度,1个自定义生物,以及对生物生成做了一些调整。
还定义了10个Feature Rule,每个Feature Rule对应不同的Netease Structure Feature,每个Netease Structure Feature对应一个结构。
该demo的python脚本较简单,实现了玩家输入维度名称时把他传送到对应维度的功能。
还添加了对test:pumpkins结构的监听,并在尝试放置test:pumpkins时以50%的概率取消生成。
自定义维度
以下解释3个自定义维度的功能及实现方法:
-
dm3
使用模板工具生成,未作任何修改的维度,生成的地形与主世界完全一致。
-
dm4
只会生成ice_plains及frozen_ocean的维度,并且使北极熊仅中该维度中生成。
-
把dm4_ice_plains及dm4_frozen_ocean的generate_for_climates属性都设置为所有温度都拥有1点生成权重,然后把所有其他群系的权重都改为0。
这样在生成基础群系时仅会生成这两种群系。
-
把dm4_ice_plains的hills_transformation及mutate_transformation设置为自身。frozen_ocean没有这两个属性,则不用设置。
这样在进行山地变异及突变变异时不会生成其他群系
-
在polar_bear的spawn_rules中设置为仅在含dm4标签的群系生成:
(见customBiomesBehaviorPack/spawn_rules/polar_bear.json)
xxxxxxxxxx
"minecraft:biome_filter": [
,
{"test": "has_biome_tag", "operator":"==", "value": "dm4"}
]
这样北极熊只会在dm4的冰原上生成。
注意:
因为目前一些硬编码的生成过程,除了ice_plains及frozen_ocean,还会生成mushroom_island,mushroom_island_shore(蘑菇岛的海岸变种),cold_beach(冰原的海岸变种),frozen_river(冰原的河流变种),以及river(cold_beach的河流变种)。因此该维度一共会有7种群系生成。
-
-
dm5
只会生成ice_plains及frozen_ocean,并且地面又矿石方块构成。在冰原上不会生成兔子,会生成3倍大小的北极熊。
-
参考dm4的第一及第二步
-
修改生成的7种群系(见dm4的注意)的方块构成。例如dm5_ice_plains中
xxxxxxxxxx
"minecraft:overworld_surface": {
"floor_depth": 7,
"floor_material": "minecraft:emerald_block",
"foundation_material": "minecraft:iron_block",
"mid_material": "minecraft:gold_block",
"top_material": "minecraft:diamond_block"
}
则群系的表面为钻石块,中间为金块,下面为铁块。
-
重写rabbit的spawn_rules,使其不在带dm5标签的群系生成:
(见customBiomesBehaviorPack/spawn_rules/rabbit.json)
xxxxxxxxxx
"minecraft:biome_filter": {
"any_of": [
{
"all_of": [
{ "test": "has_biome_tag", "operator":"==", "value": "taiga"},
{ "test": "has_biome_tag", "operator":"!=", "value": "mega"}
]
},
{
"all_of": [
{"test": "is_snow_covered", "operator":"==", "value": true},
{"test": "has_biome_tag", "operator":"!=", "value": "dm5"} //添加这一句
]
},
{"test": "has_biome_tag", "operator":"==", "value":"desert"}
]
}
-
新建一个名为neteasebiomes:dm5_polar_bear的自定义生物,除了设置为3倍大小外与原版北极熊一致
(见customBiomesBehaviorPack/entities/polar_bear.json,及customBiomesResourcePack/entity/dm5_polar_bear.entity.json)
xxxxxxxxxx
"minecraft:scale": {
"value": 3.0
},
然后为其配置spawn_rules,使其仅在dm5中生成
(见customBiomesBehaviorPack/spawn_rules/dm5_polar_bear.json)
xxxxxxxxxx
"minecraft:biome_filter": [
... ,
{"test": "has_biome_tag", "operator":"==", "value": "dm5"}
]
-
自定义特征
本demo提供的10种结构中,有9种结构为由16 * 3 * 16的玻璃-羊毛-玻璃方块(下面简称为羊毛结构),区别仅在于羊毛颜色不同。
剩余一种结构为尺寸为2 * 2 * 2的四个南瓜灯方块(简称为南瓜结构),并且在空气方块位置均放置了结构空位避免覆盖该位置的方块。
这十个结构共同组成了一个大型结构,并且整个大型结构在X、Z方向上每隔96格(6个区块)放置一次,可以在末地完整观测到。
在Feature Rule的iterations中根据区块最小坐标判断是否应放置该Feature,9个羊毛结构Feature放置时均会判断最中间黄色羊毛所在区块的生物群系是否在 0(oceans)、1(plains)、2(desert)、9(末地)、12(冰原)、46(冻洋)中,是则会尝试放置结构一次,并且放置高度均为黄色羊毛结构所在区块坐标最小点的最高非空气方块的高度。
南瓜结构放置条件与羊毛相同,不同点在于它会尝试放置三次,且x和z坐标偏移在[0, 16]内随机,高度为最终x、z坐标所在最高非空气方块的高度。
羊毛结构仅会在维度4、维度5以及末地生成,南瓜结构则会在维度4和末地生成。
下图展示了这些Feature实际放置在末地的结构:
下面以粉色羊毛结构、浅蓝色羊毛结构为例解释distribution的配置:
-
粉色羊毛结构
所有Feature均在x、z方向上每隔96格(6个区块)放置,通过math.mod来控制生成间隔。
如上图的坐标系,粉色羊毛位于(x=0, z=0)位置,因此使用math.mod(variable.originx,96)==0控制x坐标,math.mod(variable.originz,96)==0控制z坐标。
上面提到所有Feature放置时均会判断黄色羊毛所在区块坐标最小点的生物群系类型。而本demo中各羊毛结构Feature放置时的偏移均为0,即结构坐标最小点与区块坐标最小点重合。粉色羊毛结构坐标最小点与黄色羊毛结构坐标最小点之间的距离为(x=16, z=16),故query.is_biome中前两个参数分别为variable.originx + 16(黄色羊毛所在区块坐标最小点的x坐标)以及variable.originz + 16(黄色羊毛所在区块坐标最小点的z坐标)。
同时整个结构的高度以黄色羊毛结构所在区块坐标最小点的最高非空气方块的高度为准,因此计算y坐标时query.get_height_at使用的参数也为variable.originx + 16和variable.originz + 16。
xxxxxxxxxx
"distribution": {
"iterations": "math.mod(variable.originx,96)==0 && math.mod(variable.originz,96)==0 && query.is_biome(variable.originx + 16, variable.originz + 16, 0, 1, 2, 9, 12, 46)?1:0",
"coordinate_eval_order": "xzy",
"scatter_chance": 100.0,
"x": 0,
"y": "query.get_height_at(variable.originx + 16, variable.originz + 16)",
"z": 0
}
-
浅蓝色羊毛结构
如上图的坐标系,浅蓝色羊毛位于(x=0, z=16)位置,因此使用math.mod(math.mod(variable.originz, 96) + 96, 96) ==16来控制z坐标。
浅蓝色羊毛所在区块坐标最小点与黄色羊毛所在区块坐标最小点之间的距离为(x=16, z=0),因此其query.is_biome中前两个参数分别为variable.originx + 16、variable.originz,query.get_height_at参数也为variable.originx + 16、variable.originz。
xxxxxxxxxx
"distribution": {
"iterations": "math.mod(variable.originx,96)==0 && math.mod(math.mod(variable.originz,96)+96,96)==16 && query.is_biome(variable.originx + 16, variable.originz, 0, 1, 2, 9, 12, 46)?1:0",
"coordinate_eval_order": "xzy",
"scatter_chance": 100.0,
"x": 0,
"y": "query.get_height_at(variable.originx + 16, variable.originz)",
"z": 0
}
MOD卸载
当存档卸载带自定义生物群系的mod时,地图的已探索区域会保持自定义的形态,但卸载后新探索的区域会变回原版生物群系。
若对存档重新加载mod,卸载后新探索的区域会保持原版群系的形态。
常见报错
-
JSON: xxx has an error
一般为json格式有问题,可以检查一下逗号时候漏写或多写,括号是否对应。
图为多写逗号的报错
-
lookupByName can not find biome
一般为两种transform填写的群系名有问题
图为群系名多写了一个s
-
different Dimension between
一般为没有重写原版的transform,或者填写的群系与当前群系不是同一维度。
若使用“群系开发模板”进行开发,检查是否漏了第2步
图为在dm5的bamboo_jungle群系中,把hillsTransformation误填为dm3的群系
-
total weight of xxx is zero
某个温度的总权重为0。检查generate_for_climates属性的编写
图为陆地的medium温度的权重为0
-
empty Biome in xxxTransformation
transformation填写了空字符串
-
Definition of biome xxx is invalid!
继承关系有问题,检查是否继承不带维度前缀的原版群系
-
value of json is not valid
检查json的内容是否合法,例如component的拼写,各个属性的拼写等
-
Feature rule identifier xxx does not match filename yyy
一般为Feature Rules文件名与文件中的identifier不匹配。
图为文件名为overworld_gray_wool_feature的Feature Rules文件配置identifier为overworld_graywool_feature的报错。
-
No definition found for feature xxx
一般为找不到Feature Rules文件中填写的"places_feature"项对应的feature文件
图为将Feature Rules中"places_feature"值填写为error_name的报错。
-
The feature name XXX did not match the expected name of YYY
一般为Feature文件名与文件中的identifier不匹配。
图为文件名为netease_pumpkins_structure_feature的Feature文件配置identifier为pumpkins的报错。
-
Failed to load feature XXX
一般为Feature文件中places_structure项对应的结构名称填写错误,或结构文件放错了目录。
图为将test:pumpkins写为test:pumpkin导致无法正常加载结构的报错。