feat:上传mcguide-开发指南部份

This commit is contained in:
Othniel su
2024-12-23 10:57:59 +08:00
parent 7292166c88
commit 0dc59fa4f0
3297 changed files with 63375 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义维度及相关内容总览
## 维度的概念
[维度](https://minecraft-zh.gamepedia.com/维度)(Dimension)为Minecraft中平行世界的称谓包括主世界、下界、末地等。
## 维度分类
### MC内置维度
如同官方wiki中介绍的那样当前基岩版的维度包括主世界、下界和末地对应的 *DimensionId* 为0~2。
### MOD SDK自定义维度
#### 旧版自定义维度
在官方推出第五人格mod之时我们将内置的维度拓展到了 3~20也就是新增了17个自定义维度。现有开发者使用的自定义维度都是在3~20 之间的维度中选择。
#### 新版自定义维度
**问题**
旧版本的自定义维度会引起一个严重的问题:**开发者使用的自定义维度值冲突**。新增的解决方案是增大了自定义维度的设置的范围[22~int 最大值)。
**解决方案:**
尽可能的增大自定义维度ID值设置的范围多个mod的冲突发生的可能性越小。所以新版本中增加了新的自定义维度设置方案[详细查看](./1-自定义维度.md#jump_to_custom_dimension)。
## 自定义生物群系相关
在自定义生物群系中,设置群系地貌时需要指定对应的[自定义维度](./2-群系地貌.md#jump_to_terrant)。该维度设置可以采用旧版的设置也可以使用新版自定义维度方法。

View File

@@ -0,0 +1,83 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义维度
## 声明新维度
<span id="jump_to_custom_dimension"></span>
引擎中默认带有overworldnetherthe end三个原生维度以及编号为3到20的自定义维度可以直接使用。
此外还可以通过配置添加编号为22到2147483647的新自定义维度
1. addon目录中的`behavior`目录下新增`netease_dimension`文件夹
2. 添加一个以维度id命名的json文件
如dm23333.json
```json
{
"format_version": "1.14.0",
"netease:dimension_info": {
"components": { //必须有这个字段
}
}
}
```
可以使用以下python代码来生成一个随机的维度id
```python
import random, sys
print random.randint(22, sys.maxint)
```
对于三个原生维度以及18个自带的自定义维度也可以配置相应文件名的json三个原生维度对应的文件名分别为overworld.jsonnether.jsonthe end.json请勿使用维度id命名编写components字段来修改他们的属性但是一些属性无法对原生维度修改详见下面的说明。
## 维度配置
components中可以配置的组件如下
| 组件 | 类型 | 默认值 | 说明 |
| ---------------------------------------------------------- | ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| netease:dimension_type | string | minecraft:overworld | 维度的类型,可以选择以下值:<br>minecraft:overworld主世界<br>minecraft:nether下界<br>minecraft:the_end末地<br>(对三个原生维度无效) |
| netease:generator_noise | 空object | | 噪声生成器,用于生成随机凹凸的地面<br>如果没有配置任何生成器,则默认使用该生成器<br>(对三个原生维度无效) |
| netease:generator_flat | 空object | | 超平坦生成器,仅主世界和下界类型可用<br>(对三个原生维度无效) |
| netease:generator_legacy | 空object | | 旧世界/经典(有限地图)生成器,仅主世界类型可用<br>(对三个原生维度无效) |
| netease:ban_vanilla_feature | 空object | | 清除原版feature可解决类似空岛玩法天空悬浮结构问题仅主世界类型维度可用 |
| netease:spawn_biomes | array(string) | 该维度下的forest, forest_hills, plains, taiga, taiga_hills, jungle, jungle_hills | 该维度下可供玩家出生的群系名称的列表。<br>请确保列表的群系会生成在该维度。 |
| [netease:biome_source](./2-群系地貌.md#8-4.群系源节点类型) | array(dict) | | 该维度下的群系源,仅主世界类型可用<br>(对三个原生维度无效) |
| netease:ban_vanilla_mineshaft | 空object | | 屏蔽废弃矿井 |
| netease:ban_vanilla_monument | 空object | | 屏蔽海底遗迹 |
| netease:ban_vanilla_mansion | 空object | | 屏蔽林地府邸 |
| netease:ban_vanilla_temple | 空object | | 屏蔽神庙 |
| netease:ban_vanilla_pillageroutpost | 空object | | 屏蔽掠夺者前哨 |
| netease:ban_vanilla_ruinedportal | 空object | | 屏蔽破坏的传送门(仅主世界类型维度可用) |
| netease:ban_vanilla_ruins | 空object | | 屏蔽水下遗迹 |
| netease:ban_vanilla_shipwreck | 空object | | 屏蔽沉船 |
| netease:ban_vanilla_stronghold | 空object | | 屏蔽要塞 |
| netease:ban_vanilla_village | 空object | | 屏蔽村庄 |
例如CustomBiomesMod中的dm23333.json
```json
{
"format_version": "1.14.0",
"netease:dimension_info": {
"components": {
"netease:dimension_type": "minecraft:overworld", //类型为主世界
"netease:generator_noise": {}, //使用噪声生成器
"netease:spawn_biomes": ["dm23333_ice_plains"] //玩家会在冰原下出生
}
}
}
```
注:
- 自定义末地推荐在群系中配置不生成末影龙及相关逻辑(参考:[群系地貌](./2-群系地貌.md#jump_to_no_spawn_dragon)),即使开了末影龙逻辑也不会生成传送门,有需要可以搭配自定义传送门使用。
- 如果已经进入过某个维度该维度地形已被存档那么再配置维度类型可能会出现存档地形和生成地形融合的奇怪现象可以在进入维度前通过UpgradeMapDimensionVersion接口提升该维度版本号废弃原本的存档信息。

View File

@@ -0,0 +1,148 @@
---
front:
hard: 入门
time: 分钟
---
# 生物生成
## 概述
开发者可以使用原版addon的`spawn_rules`功能控制自定义维度中的生物生成。
## spawn_rules使用方法
1.在addon的bevavior目录下新增spawn_rules文件夹
2.创建一个json文件并命名如example.json例子
```python
{
"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"
}
}
]
}
}
```
description参数解释
| 参数 | 类型 | 解释 |
| --- | --- | --- |
| identifier | str | 该spawn rule的identifier格式为namespace:name |
| population_control | str | 生成生物的种类,每一种类都有生成个数的限制,可选的值为:<br>animal<br>monster<br>water_animal<br>villager<br>ambient<br>cat<br>pillager |
conditions参数解释
| 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 |
## 自定义群系的spawn_rules
利用condition中的minecraft:biome_filter过滤自定义群系的tag例如群系开发模板自带的dm3等tag或者其他自定义tag。
## demo解释
示例[CustomBiomesMod](../../13-模组SDK编程/60-Demo示例.md#CustomBiomesMod)中对dm4于dm5两个自定义维度的生物生成做了一些调整。
- dm4
使北极熊仅在该维度中生成,不会在其他维度的冰原群系生成。
1. 在polar_bear的spawn_rules中设置为仅在含dm4标签的群系生成
见customBiomesBehaviorPack/spawn_rules/polar_bear.json
```json
"minecraft:biome_filter": [
...,
{"test": "has_biome_tag", "operator":"==", "value": "dm4"}
]
```
- dm5
在冰原上不会生成兔子会生成3倍大小的北极熊。
1. 重写rabbit的spawn_rules使其不在带dm5标签的群系生成
见customBiomesBehaviorPack/spawn_rules/rabbit.json
```json
"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"}
]
}
```
2. 新建一个名为neteasebiomes:dm5_polar_bear的自定义生物除了设置为3倍大小外与原版北极熊一致
见customBiomesBehaviorPack/entities/polar_bear.json及customBiomesResourcePack/entity/dm5_polar_bear.entity.json
```json
"minecraft:scale": {
"value": 3.0
},
```
然后为其配置spawn_rules使其仅在dm5中生成
见customBiomesBehaviorPack/spawn_rules/dm5_polar_bear.json
```python
"minecraft:biome_filter": [
... ,
{"test": "has_biome_tag", "operator":"==", "value": "dm5"}
]
```

View File

@@ -0,0 +1,530 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义特征
## 1.概述
该功能仅在结构保存时需要开启实验性玩法。
开发者可以通过配置特征(features)与特征规则(feature_rules)控制自定义群系的区块生成时,基础地形生成完毕后的后处理阶段。
特征可以理解为一些方块的组合,例如原版的矿物或树木;特征规则定义如何将这些特征放置到地形中。
除了支持原版addon的特征类型我们还新增了一种基于结构方块导出结构的特征。
Netease Structure Feature和Feature Rules的方式在地形生成时自动在区块上放置多个由结构方块导出的结构。
**下界和超平坦世界无法生成自定义特征**
**自网易1.21版本起features与feature_rules的identifier需要添加命名空间且自定义特征相关格式版本更新至1.14.0**
**本示例中的命名空间为custombiomes开发者可以自定义命名空间推荐与mod名称一致**
## 2.参考资料
1. [官方wiki](https://minecraft.gamepedia.com/Bedrock_Edition_features_documentation)对特征及特征规则的解释与示例
这个页面上列举了原版的特征,包括单方块,矿簇等
2. 不使用feature_rules而直接在自定义群系json中配置feature的方法见[官方wiki](https://minecraft.gamepedia.com/Bedrock_Edition_biomes_documentation#Schema)的群系json结构解释
3. 原版features的json见“Mod PC开发包”的`data/definitions/features`目录
4. 原版feature rules的json见“Mod PC开发包”的`data/definitions/feature_rules`目录
## 3.特征features
特征的json文件应放在行为包的 netease_features 目录下
原版特征见参考资料1可以直接在此目录下定义下面主要讲解如何利用结构方块制作**结构特征**。
注意: 原版特征例如minecraft:ore_feature等方式不支持放置方块实体通过这种方式放置的方块实体会缺失原有方块实体功能也会导致部分方块实体缺失部分外观例如箱子活塞或者自定义方块实体外观等等。如果想要通过特征放置方块实体可以尝试使用下文结构特征来进行放置。
### 3-1.结构
结构指使用[结构方块](https://minecraft-zh.gamepedia.com/index.php?title=%E7%BB%93%E6%9E%84%E6%96%B9%E5%9D%97)保存的地图模板,结构的编辑和导出需要玩家处于创造模式下,并开启实验性玩法。
#### 3-1-1.结构方块的获取与放置
可通过指令`/give @p structure_block`获取结构方块
结构方块放置后可在世界中看到结构的白色轮廓。使用结构方块可打开其GUI可在GUI中编辑结构的大小、距离结构方块的偏移。
结构中红、蓝、绿三线交汇点为该结构方块的坐标最小点,结构的放置都是从该点所在方块开始的。
若不希望结构中的空气方块在放置时覆盖掉其他方块,可通过指令`/give @p structure_void`获取[结构空位](https://minecraft-zh.gamepedia.com/%E7%BB%93%E6%9E%84%E6%96%B9%E5%9D%97#.E7.BB.93.E6.9E.84.E7.A9.BA.E4.BD.8D),并放置在相应的空气方块上。
![](./picture/custombiome/3-1.png)
#### 3-1-2.结构的导出
结构特征支持的单个结构最大尺寸为一个区块的大小及16x255x16若超过最大尺寸超出范围的方块可能不会成功放置若方块在世界中的高度超过255也不会成功放置建议结构高度不要设置过高。
结构特征**不支持包含实体**功能,即使结构中保存了实体,也不会生成。
在结构方块GUI界面模式选择"保存",点击导出即可导出该结构了。
导出后将mcstructure文件放在behavior/structures/xxx目录下xxx目录一般可以使用mod名称。
然后在后续的使用中,“文件夹名:文件名”即为该结构的identifier
例如下图中的结构identifier为test:grayWool
![](./picture/custombiome/3-1-1.png)
若结构中包含火方块通过NeteaseStructureFeature放置的火与[永恒之火](https://minecraft-zh.gamepedia.com/%E7%81%AB#.E6.B0.B8.E6.81.92.E4.B9.8B.E7.81.AB)相似,不会熄灭、不会扩散,但依旧有燃烧伤害。
#### 3-1-3.原版测试指令
**仅供测试仅在pc开发包上可以使用**如需要在python代码中放置结构见[python事件及接口](#python事件及接口)
通过`/placefeature featureName x y z`指令可直接放置结构
### 3-2.结构特征的json结构
**特征的identifier必须为小写并且文件名要与identifier中冒号后的部分一致**
```json
netease_pumpkins_structure_feature.json
{
"format_version": "1.14.0", // 格式版本为1.14.0
"netease:structure_feature": { // feature类型必须为netease:structure_feature
"rotation":0, //可选项,将结构体按照结构的(0,0)点旋转默认为0可选值为90180270
"description": {
"identifier": "custombiomes:netease_pumpkins_structure_feature" // 该feature的identifiercustombiomes为其命名空间开发者可以自行定义
},
"places_structure": "test:pumpkins" // 放置的结构的identifier
}
}
```
## 4.特征规则feature_rules
特征规则的json文件应放在行为包的 netease_feature_rules 目录下
**特征规则的identifier必须为小写并且文件名要与identifier中冒号后的部分一致**
### 4-1.基本流程
结合一个简单的特征规则json来理解特征是如何生成到世界的
```json
overworld_pumpkins_feature.json
{
"format_version": "1.14.0", // 格式版本为1.14.0
"minecraft:feature_rules": {
"description": {
"identifier": "custombiomes:overworld_pumpkins_feature", // 该feature_rule的identifiercustombiomes为其命名空间开发者可以自行定义
"places_feature": "custombiomes:netease_pumpkins_structure_feature" // 该feature_rules所放置的feature的identifier
},
"conditions": { // 控制feature生成条件
"placement_pass": "surface_pass", // 控制feature_rules的执行顺序
"minecraft:biome_filter": [ // 控制feature会在哪些生物群系中生成
...
]
},
"distribution": { // 控制featuer的分布
"iterations": 1,
"coordinate_eval_order": "xzy",
"scatter_chance": 100.0,
"x": 0,
"y": 100,
"z": 0
}
}
}
```
一个feature_rule可以理解为对一个feature如何生成的定义。如果想将一个feature_rule应用到多个feature可以使用原版的Aggregate Feature见参考资料1
feature的生成是与单个区块绑定的因此单个feature的体积不应超过当前区块的范围对于结构特征也是如此但是下面会讲到如何利用其他方法生成大体积的建筑。
当一个区块生成基本地貌后会进行一个后处理阶段例如添加原版的矿物植被等feature_rules也是在这个时候生效。
feature_rule中的conditions决定了这个feature会在哪些群系中生成以及生成的先后顺序
而distribution定义了对于每个群系类型符合的区块是否要生成这个feature生成的次数以及生成的位置
1. 根据iterations的数值进行迭代
2. 每次迭代中会进行一次随机大于scatter_chance的概率则进行第3步
3. 根据coordinate_eval_order以及xyz的内容决定该次迭代所生成的feature的实际位置。
### 4-2.参数解释
conditions中的参数解释
| 参数 | 类型 | 解释 |
| --- | ---| --- |
| placement_pass | str |后处理阶段一共分为若干个步骤依次按顺序进行处理完一个步骤的feature_rules后再处理下一个步骤的。这些步骤按顺序分别为<br>first_pass<br>before_underground_pass<br>underground_pass<br>after_underground_pass<br>before_surface_pass<br>surface_pass<br>after_surface_pass<br>before_sky_pass<br>sky_pass<br>after_sky_pass<br>final_pass |
|minecraft:biome_filter|array|哪些群系可以应用该feature_rule|
distribution中的参数解释
| 参数 | 类型 | 解释 |
| --- | ---| --- |
|iterations|molang|该区块尝试生成feature的次数|
|scatter_chance|float|每次迭代生成feature的概率|
|coordinate_eval_order|str|实际位置xyz三个坐标的生成顺序默认为xzy|
|x/y/z|molang或object|实际位置各个坐标的计算方法返回相对区块最小坐标的值即x和z应在0-15内|
在iterations以及x/y/z中可以使用的variable
| 变量 | 解释 |
| --- | ---|
|variable.originx|该区块的最小x坐标|
|variable.originz|该区块的最小z坐标|
如果在coordinate_eval_order中y轴排在最后则“y”字段的molang有可以额外使用的variable
| 变量 | 解释 |
| --- | ---|
|variable.worldx|实际位置的x轴的实际坐标|
|variable.worldz|实际位置的z轴的实际坐标|
在distribution中的molang可使用以下query
- query.get_height_at(x, z)
- 描述
根据x、z坐标获取其上最高非空气方块的高度可传入当前区块之外的坐标。通常用于y轴实际坐标的生成
- 参数
| 参数名 | 数据类型 | 说明 |
| ------ | -------- | --------- |
| x | int | x世界坐标 |
| z | int | z世界坐标 |
- query.is_biome(x, z, biomes...)
- 描述
判断在x、z坐标上的生物群系是否为目标生物群系可传入当前区块之外的坐标。一般用于由多个结构组成的大型结构的生成
- 参数
| 参数名 | 数据类型 | 说明 |
| :----- | :------- | :----------------------------------------------------------- |
| x | int | x世界坐标 |
| z | int | z世界坐标 |
| biomes | Args... | 生物群系的枚举值int可参照minecraft枚举值文档中的<a href="../../../../mcdocs/1-ModAPI/枚举值/BiomeType.html" rel="noopenner"> BiomeType </a> |
- 示例
如果我们要获取当前区块是否在沙漠或树林,可以写成
```json
query.is_biome(variable.originx + 15, variable.originz + 15, 2 ,4)
```
- 备注
1.一个区块内可能存在多个生物群系类型,不管是水平方向还是竖直方向,例如**繁茂洞穴群系、平原群系**可能在**同一区块的不同高度****沙漠群系**、**平原群系**可能在同一区块同一高度的不同区块内位置
2.query.is_biome函数暂不支持传入y坐标默认判断y坐标为0时的群系
- query.noise(num1, num2)<a name="query.noise"></a>
- 描述
用于产生伪随机数,传入两个数,返回一个 -1~1 之间的浮点数。当传入的两个参数相同时query.noise得到的结果也相同。
可用于控制由多个结构组成的大型结构的概率生成。
- 参数
| 参数名 | 参数类型 | 说明 |
| ------ | -------- | ---------- |
| num1 | float | 传入参数一 |
| num2 | float | 传入参数二 |
### 4-3.示例
```json
{
"format_version": "1.14.0", // 格式版本为1.14.0
"minecraft:feature_rules": {
"description": {
"identifier": "custombiomes:overworld_pumpkins_feature", // 该feature_rule的identifier
"places_feature": "custombiomes:netease_pumpkins_structure_feature" // 该feature_rule所放置的feature的identifier
},
"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 - 48, 96) == 0 && math.mod(variable.originz - 48, 96) == 0 && query.is_biome(variable.originx - 17, variable.originz - 17, 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 ] // 选取范围,不包括最大值
},
"y": "query.get_height_at(variable.worldx, variable.worldz)", // variable.worldx为最终放置feature的x坐标variable.worldz同理
"z": {
"distribution": "uniform",
"extent": [ 0, 16 ]
}
}
}
}
```
## 5.python事件及接口
- PlaceNeteaseStructureFeatureEvent事件(
结构特征生成的事件,详见<a href="../../../../mcdocs/1-ModAPI/事件/世界.html#placeneteasestructurefeatureevent" rel="noopenner"> MOD SDK文档 </a>。
- PlaceStructure接口
手动在世界中放置结构,详见<a href="../../../../mcdocs/1-ModAPI/接口/世界/地图.html#placestructure" rel="noopenner"> MOD SDK文档 </a>。
## 6.大型结构特征的生成
大于16x16的特征我们需要按照一个区块16x16为大小来将其分割成多个子特征。
以CustomBiome示例中的羊毛特征为例假设我们需要设计一个48x48大小的大型特征那将会分割出3x3一共9个子结构并为每个结构编写对应的feature以及feature_rule。
重点在于通过feature_rule的配置使得9个子结构在生成时按照原来的顺序排列如何保证大型特征在群系边缘生成时的完整性以及如何使生成的高度不会错位。
排列以及完整性主要通过将scatter_chance都设为100然后靠iterations的配置实现通过一些方法使9个子结构在合适的位置同时为0或同时为1。高度主要通过y的配置实现需要使9个子结构的输出相同。
![](./picture/custombiome/3-3.png)
### 6-1.控制多个特征的排列
这里我们求余的特性来达到这种效果。如果以左下特征(粉色羊毛)的最小坐标点为原点(0, 0),那么中央特征(黄色羊毛)的最小坐标点就是(16, 16)
那么如果我们设定一个数值当左下特征最小点的x和z轴除以该值的余数为0那么中央特征最小点的x和z轴除以该值的余数就是16以此类推。
该数值的意义可以理解为每隔一段距离尝试生成一个大型特征而且为了让16*16的结构恰好填充在一个区块内该数值需要为16的倍数。这里我们假设为96那么我们可以写出这两个特征的iterations的条件:
```json
左下特征:
"iterations": "math.mod(variable.originx, 96) == 0 && math.mod(variable.originz, 96) == 0 ? 1:0"
中央特征:
"iterations": "math.mod(variable.originx - 16, 96) == 0 && math.mod(variable.originz - 16, 96) == 0 ? 1:0"
```
### 6-2.处理群系边缘的情况
这里分为两种情况有不同的解决方法。
1. 特征生成后不需要用到群系特征,例如刷怪
这种情况意味着不需要整个特征都坐落在特定的群系上允许部分越过群系边缘。CustomBiome示例中的羊毛特征使用的是这种方法。
首先minecraft:biome_filter只添加维度的过滤不可以写具体群系的过滤即允许子特征在所有群系都可能生成。
然后我们通过在iterations中使用query.is_biome来限制特征所在的群系以及完整性。
还是以3x3羊毛特征为例假设我们规定左下特征必须落在沙漠群系内而其他子特征不作限制则可以得出左下特征最小点的群系为沙漠而中央特征最小点的x和z轴减去16后所在的群系也是沙漠以此类推。
所以我们把iterations写成
```json
左下特征:
math.mod(variable.originx, 96) == 0 && math.mod(variable.originz, 96) == 0
&& query.is_biome(variable.originx + 15, variable.originz + 15, 2) ? 1:0
中央特征:
math.mod(variable.originx - 16, 96) == 0 && math.mod(variable.originz - 16, 96) == 0
&& query.is_biome(variable.originx - 1, variable.originz - 1, 2) ? 1:0
```
2. 特征生成后需要用到群系特征
这意味着每个子特征都需要在正确的群系上首先在minecraft:biome_filter中添加特性群系的过滤器
对于每个子特征我们需要判断3x3整个区域都落在指定群系上才进行生成。
所以我们把iterations写成
```json
左下特征:
math.mod(variable.originx, 96) == 0 && math.mod(variable.originz, 96) == 0
&& query.is_biome(variable.originx+15, variable.originz+15, 2)
&& query.is_biome(variable.originx+31, variable.originz+15, 2)
&& query.is_biome(variable.originx+47, variable.originz+15, 2)
&& query.is_biome(variable.originx+15, variable.originz+31, 2)
&& query.is_biome(variable.originx+31, variable.originz+31, 2)
&& query.is_biome(variable.originx+47, variable.originz+31, 2)
&& query.is_biome(variable.originx+15, variable.originz+47, 2)
&& query.is_biome(variable.originx+31, variable.originz+47, 2)
&& query.is_biome(variable.originx+47, variable.originz+47, 2) ? 1 : 0
中央特征:
math.mod(variable.originx - 16, 96) == 0 && math.mod(variable.originz - 16, 96) == 0
&& query.is_biome(variable.originx-1, variable.originz-1, 2)
&& query.is_biome(variable.originx+15, variable.originz-1, 2)
&& query.is_biome(variable.originx+31, variable.originz-1, 2)
&& query.is_biome(variable.originx-1, variable.originz+15, 2)
&& query.is_biome(variable.originx+15, variable.originz+15, 2)
&& query.is_biome(variable.originx+31, variable.originz+15, 2)
&& query.is_biome(variable.originx-1, variable.originz+31, 2)
&& query.is_biome(variable.originx+15, variable.originz+31, 2)
&& query.is_biome(variable.originx+31, variable.originz+31, 2) ? 1 : 0
```
### 6-3.控制高度
通常特征的y轴我们会使用某个坐标上最高非空气方块的高度那需要每个子特征获取的坐标一致才能使各个子特征在高度上不会错位。
还是以3x3羊毛特征为例假设我们规定整个特征都以左下特征最小点的高度为准那对于中央特征则需要获取最小点坐标各减去16后的位置的高度以此类推
最后写成
```json
左下特征:
"y": "query.get_height_at(variable.originx, variable.originz)"
中央特征:
"y": "query.get_height_at(variable.originx-16, variable.originz-16)"
```
### 6-4.控制生成的随机性
我们可以让特征按照一定的间距的基础上添加一点随机性需要用到伪随机函数query.noise。为了保证特征的完整性需要保证每个子特征传入相同的参数。
还是以3x3羊毛特征为例方便起见我们直接使用左下特征最小点坐标为参数那对于中央特征则是最小点坐标各减去16为参数以此类推。
假设想要以50%的概率的概率生成,那么需要在[处理群系边缘的情况](#处理群系边缘的情况)的基础上加上这样的条件:
```json
左下特征:
... && math.abs(query.noise(variable.originx, variable.originz))<0.5
中央特征:
... && math.abs(query.noise(variable.originx-16, variable.originz-16))<0.5
```
## demo解释
CustomBiome示例中存放了10种结构见`behavior/structures/test`其中有9种结构为由16x3x16的玻璃-羊毛-玻璃方块下面简称为羊毛结构区别仅在于羊毛颜色不同。剩余一种结构为尺寸为2x2x2的四个南瓜灯方块简称为南瓜结构并且在空气方块位置均放置了结构空位避免覆盖该位置的方块。
然后每个结构都对应了一个结构特征,见`behavior/netease_features`,以及一个特征规则,见`behavior/netease_feature_rules`
在末地以及dm4维度中这十个特征共同组成了一个大型特征并且整个大型特征在X、Z方向上每隔96格6个区块放置一次。九种羊毛会在同一个高度上按照固定的顺序排列而南瓜特征则会尝试放置三次且x和z坐标偏移在[0, 16]内随机高度为最终x、z坐标所在最高非空气方块的高度。
此外南瓜特征还会在dm5维度中单独生成。
下图展示了整个大型特征实际放置在末地的结构:
![](./picture/custombiome/3-3.png)
在feature_rule的iterations中根据区块最小坐标判断是否应放置该feature9个羊毛结构放置时均会判断最中间黄色羊毛所在区块的生物群系是否在 0oceans、1plains、2desert、9末地、12冰原、46冻洋是则会尝试放置结构一次并且放置高度均为黄色羊毛结构所在区块坐标最小点的最高非空气方块的高度。
对于[处理群系边缘的情况](#处理群系边缘的情况),示例采用的是第一种解决方法,即只要黄色羊毛所在群系符合,则会生成整个结构,不在乎周围其他羊毛所在的群系。
下面以粉色羊毛结构、浅蓝色羊毛结构为例解释distribution的配置
* 粉色羊毛结构
均在x、z方向上每隔96格6个区块放置通过math.mod来控制生成间隔。
如上图的坐标系,粉色羊毛位于(x=0, z=0)位置因此使用math.mod(variable.originx,96)==0控制x坐标math.mod(variable.originz,96)==0控制z坐标。
上面提到所有结构放置时均会判断黄色羊毛所在区块的生物群系类型由区块内坐标最大点决定。而本demo中各羊毛结构放置时的偏移均为0即结构坐标最小点与区块坐标最小点重合与区块坐标最大点之间存在(x=15, z=15)的偏移。粉色羊毛结构坐标最小点与黄色羊毛结构坐标最小点之间的距离为(x=16, z=16)故query.is_biome中前两个参数分别为variable.originx + 15 + 16黄色羊毛所在区块坐标最大点的x坐标以及variable.originz + 15 + 16黄色羊毛所在区块坐标最大点的z坐标
同时整个结构的高度以黄色羊毛结构所在区块坐标最小点的最高非空气方块的高度为准因此计算y坐标时query.get_height_at使用的参数为variable.originx + 16和variable.originz + 16。
```json
"distribution": {
"iterations": "math.mod(variable.originx, 96) == 0 && math.mod(variable.originz, 96) == 0 && query.is_biome(variable.originx + 31, variable.originz + 31, 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(variable.originz - 16, 96) == 0来控制z坐标。
浅蓝色羊毛所在区块坐标最小点与黄色羊毛所在区块坐标最小点之间的距离为(x=16, z=0)因此其query.is_biome中前两个参数分别为variable.originx + 15 + 16、variable.originz + 15 + 0query.get_height_at参数为variable.originx + 16、variable.originz。
```json
"distribution": {
"iterations": "math.mod(variable.originx, 96) == 0 && math.mod(variable.originz - 16, 96) == 0 && query.is_biome(variable.originx + 31, variable.originz + 15, 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
}
```
## 常见报错
1. Feature rule identifier xxx does not match filename yyy
一般为Feature Rules文件名与文件中的identifier不匹配。
图为文件名为overworld_gray_wool_feature的Feature Rules文件配置identifier为overworld_graywool_feature的报错。
![](./picture/custombiome/3-4.png)
2. No definition found for feature xxx
一般为找不到Feature Rules文件中填写的"places_feature"项对应的feature文件
图为将Feature Rules中"places_feature"值填写为error_name的报错。
![](./picture/custombiome/3-5.png)
3. The feature name XXX did not match the expected name of YYY
一般为Feature文件名与文件中的identifier不匹配。
图为文件名为netease_pumpkins_structure_feature的Feature文件配置identifier为pumpkins的报错。
![](./picture/custombiome/3-6.png)
4. Failed to load feature XXX
一般为Feature文件中places_structure项对应的结构名称填写错误或结构文件放错了目录。
图为将test:pumpkins写为test:pumpkin导致无法正常加载结构的报错。
![](./picture/custombiome/3-7.png)

View File

@@ -0,0 +1,122 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义传送门DEMO
传送门demo为[portalGateDemo](../../13-模组SDK编程/60-Demo示例.md#portalGateDemo),并结合自定义维度使用。
### 玩法介绍
1. 用萤石围成一个4x4的方框对指定点的萤石使用骨粉会消耗1个骨粉然后方框内布满传送门方块进入传送门方块将传送到新自定义维度。
2. 传送完毕portal forcer功能
如果附近有自定义传送门,把玩家移动到传送门附近;
否则在玩家附近创建一个传送门并且把数据保存到level extraData中
在地图中敲坏传送门同时删除level extraData中的传送门信息。
### Mod配置说明
1. DEMO配置两个带有传送组件的[自定义方块](../2-自定义方块/0-自定义方块概述.md#customBlockJump),一个目标设置为自定义维度,一个设置到主世界
2. 按照本文档配置自定义维度
3. 传送门配置解释:
- 设置门形状:
```python
self.pattern =[
'####',
'#**#',
'#**#',
'####',
]
```
- 设置门方块定义:
```
self.defines ={
'#':'minecraft:glowstone',
'*':'minecraft:air'
}
```
- 设置传送门激活物品信息(骨粉)
```
self.useOnItemName = 'minecraft:dye'
self.useOnItemAux = 15
```
- 设置传送门边框可激活的位置
相对之前的pattern中定义的位置
<img src="./picture/portal_zuobiao.png" />
```
self.touchPos =[(3,1),(3,2)]
```
4. 激活检测
当玩家使用物品时监听 **ServerItemUseOnEvent** 事件,检测是否为设置的物品,如果是的话就进行传送门搭建的检测,具体的匹配算法接口见<a href="../../../../mcdocs/1-ModAPI/接口/世界/地图.html#detectstructure" rel="noopenner"> DetectStructure接口 </a>
对位置(3,1)或者(3,2)使用骨粉可以激活传送门,如下图所示。
<img src="./picture/portal_active.png" />
5. Portal Forcer功能
通过监听事件<a href="../../../../mcdocs/1-ModAPI/事件/玩家.html#dimensionchangefinishserverevent" rel="noopenner"> DimensionChangeFinishServerEvent </a>完成引擎内类似Portal Forcer功能进地狱门传到地狱之后的逻辑
主要流程如下:
切换维度完成之后,在玩家附近寻找传送门,如果找到,那么把玩家移到找到的传送门附近;
否则在玩家附近创建一个传送门并且把传送门信息保存到level extraData中。
该功能请查阅传送门demo。
6. 自定义传送门方块相关特性:
- 若通过服务端blockInfo组件的SetBlockNew接口放置传送门方块
- 附加值'aux'设为1时该方块延伸方向与X轴相同播放particle_north_south对应的粒子
- 附加值'aux'设为2时该方块延伸方向与Z轴相同播放particle_east_west对应的粒子。
- **避免将附加值'aux'设为0。**
- 还可以在游戏内通过指令/setblock放置方块**注意'aux'值应设为1或2。**
如下为在(0, 65, 0)处放置aux值为2的customblocks_test_portal_blue方块的指令
`/setblock 0 65 0 customblocks_test_portal_blue 2`
- 手动放置的传送门方块附加值'aux'始终为0无论它朝向哪里**不建议开发者手动放置传送门方块。**
- 目标维度与当前维度相同时,将不会进行传送。
- 只有玩家才能够通过自定义传送门方块进行传送。
- 同一玩家存在一定的传送冷却时间,不会连续传送。
- 传送前后玩家坐标不发生改变。
### 常见问题
1.PC开发包出现如下断言
![image-20220830151510241](./picture/portal_aux_assert.png)
原因:由于手动摆放的附加值(aux)为0所以通过结构方块加载具有手动摆放的传送门方块时会出现此断言
解决方案:可使用/setBlock指令设置传送门方块位置来解决此问题注意'aux'值应设为1或2。

View File

@@ -0,0 +1,318 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义大型特征
## 0.预备知识:
### 0-1.拼图方块简介:
![Jigsaw_Block_29_JE3_BE2](./picture/jigsaw_block.png)
拼图方块(线锯方块)是用于生成一些结构的技术性方块,拼图方块不会生成在世界中,部分结构包含拼图方块(掠夺者前哨站和村庄等),但这些拼图方块在自然生成时被转换为了其他结构,使拼图方块不会生成在世界中(在游戏中可以使用 /give @s jigsaw 指令获取拼图方块)。
将拼图方块放置到游戏中点击会出现UI界面如下图:
![image-20230519114449918](./picture/jigsaw_block_config.png)
### 0-2.拼图方块属性介绍:
1.目标池:
- 指此拼图方块用于选取结构的结构池
- 结构池的定义可查看[1-4-2.结构池](#1-4-2.结构池配置)配置
- 默认值为"minecraft:empty"
2.名称:
- 此拼图方块的名称
- 默认值为"minecraft:empty"
3.目标名称:
- 当结构从目标池中生成时要对接拼图方块的名称
- 默认值为"minecraft:empty"
4.变为:
- 指的是拼图方块在整个功能被放置后会转变的方块状态
- 默认值为"minecraft:air"
5.接点类型:
- 只在方块朝上或朝下时有效。
- 含有两种连接类型(可旋转和固定):
1.可旋转生成时拼图方块会随机将目标结构或实体置于与该拼图方块处于同一XZ轴的结构方块的边界内。默认为此类型。
2.固定:生成时,拼图方块会直接把目标结构或实体置于自身所朝的方向(上方或下方)。可用于连接结构和固定的实体。
## 1.自定义大型特征的生成
在2.7版本之前,想要在游戏中生成大型结构必须通过在[特征规则](./4-自定义特征.md#6大型结构特征的生成)中通过调整位置等参数控制iterations来将一个个16*16的小型结构拼接为大型结构
其中iterations的配置有时会相当复杂并且随机性不高生成结构较为生硬。为解决以上问题在2.7版本,我们引入了自定义大型结构特征来解决上述问题。
![image-20230418161948622](./picture/large_feature1.png)
### 1-1.什么是自定义大型结构特征?
自定义大型特征参考了原版村庄的生成逻辑,允许开发者通过配置结构池,大型结构特征生成规则来控制生成,并且在不同的位置,不同的群系,不同种子的情况下,生成不同的大型结构特征。
大型结构特征的原理就是通过放置一定数量的带有拼图方块的小型结构,再根据拼图方块的规则去随机生成符合规则的下一个结构,不断进行深度递归拼接而成的大型结构。
### 1-2.自定义大型结构特征简介
自定义大型结构特征的生成是一个递归的过程,首先从中心结构池抽取一个中心结构摆放,这个中心结构带有拼图方块,则会根据拼图方块设定的目标结构池,寻找下一个需要摆放的结构,拼接成功后再遍历第二个结构中的拼图方块来寻找可以拼接的结构,依次递归,直至满足最大递归深度或找不到新的可拼接结构,则会从终结结构池选择一个终结结构进行收尾,类似下图。
![image-20230519170329439](./picture/large_feature_spawn_line.png)
### 1-3.MCStudio中放置拼图方块并导出结构
1. 打开MCStudio并切换到地图编辑器
![image-20230519145446781](./picture/mcstudio_1.png)
2. 制作好用于拼接的结构,并将其放置到地图中
![image-20230519145649574](./picture/mcstudio_2.png)
3. 选择笔刷→拼图方块笔刷,正确配置拼图方块的属性,并使用笔刷放置到地图中,如下图所示:
![图片](./picture/jigsawplace.png)
> 注1关于拼图方块笔刷的属性你可以参考[拼图方块笔刷属性说明](../../../14-地图制作/6-笔刷工具.md#_9-拼图方块笔刷)。
> 注2拼图方块有方向属性摆放时拼图方块的箭头会指向玩家所在方向拼图方块会根据方向属性对接其他结构中的拼图方块**例如方向朝右的拼图方块,会对接方向朝左的拼图方块**
> 注3除了直接使用拼图方块笔刷进行放置开发者也可以在拼图方块摆放完成后进入游戏模式再右击拼图方块会弹出UI界面并填写配置完成后点击完成。
> 注4因为拼图方块既可以从结构池中选择生成结构又可以作为被选出结构的连接点为降低复杂度我们在对拼图方块笔刷做了类型区分
> 1. 源方块类型: 假设此拼图方块用来从结构池寻找下一个可拼接结构并生成,只需填写【目标池】(可参考[结构池](#1-4-2.结构池配置)定义)和【目标名称】。
> 2. 目标方块类型:假设此拼图方块用来充当被选出结构的连接点,只需填写【名称】。
> 3. 自定义类型:实际上同一个拼图方块可以同时是源类型和目标类型的,只需要根据需要填写对应的属性值。
4. 在中心结构上放置源类型的拼图方块
![image-20230519153158150](./picture/mcstudio_4.png)
![image-20230519153158150](./picture/mcstudio_4a.png)
5. 在其他结构中放置拼图方块,并填写好配置
![image-20230519153647172](./picture/mcstudio_6.png)
![image-20230519153647172](./picture/mcstudio_5.png)
6. 重复上述步骤,将结构中所有需要连接的地方都放入拼图方块,并填写好配置
![image-20230519153958028](./picture/mcstudio_7.png)
7. 在MCStudio地图编辑器下选中“选取”选中结构并点击“保存为结构”
![image-20230519154626390](./picture/mcstudio_8.png)
![image-20230519154651901](./picture/mcstudio_9.png)
8. 输入结构名称后点击保存即可(保存的结构即可在[结构池](#1-4-2.结构池配置)配置中使用),重复上述步骤,将所有结构导出保存。
![image-20230519161149896](./picture/mcstudio_10.png)
9. 切换到关卡编辑器配置对应的结构池和大型特征生成规则配置,将之前导出的结构配置到对应的中心池、道路中间池、终结池中。
![图片](./picture/configstructure.png)
![图片](./picture/largefeatureconfig.png)
10. 运行游戏,进入对应的维度和群系,查看结构生成效果
![image-20230418161948622](./picture/large_feature1.png)
11. 为了方便开发者调试,地图编辑器在地形工具内新增了大型结构工具,用于快速放置结构池的结构,便于开发者快速验证自己的配置效果,详情可以参考[大型结构工具](../../../14-地图制作/7-地形工具.md#_8大型结构)。
![图片](./picture/placelargefeature.gif)
### 1-4.自定义大型结构配置相关
#### 1-4-1.文件结构
- behavior_back
- netease_large_feature_pools结构池配置
- xxx_pools.json
- ...
- netease_large_feature_rules大型结构生成规则配置
- xxx_feature_rules.json
- ...
- structures
- test(文件夹名称)
- xxx.mcstructure
- ...
- ....
#### 1-4-2.结构池配置<span id = "1-4-2.结构池配置"></span>
简介:结构池主要用于存储结构,在需要时可以根据权重从池子中选出合适的结构进行拼接
举例:原版村庄中不同位置也会有类似池子,比如房屋池,中心点池,道路池等等,主要用于结构的随机
在behavior_back/netease_large_feature_pools文件夹下创建xxx.json文件xxx为文件名
```json
{
"format_version": "1.18.0",
"netease:large_feature_pool": {
"description": {
"identifier": "netease:centerPool" //结构池的identifier,用于拼图方块中目标池的填写(必填)
},
"pool": [
{ //结构池配置
"structure_name": "netease:house_t_center", //结构名称(必填)
"path": "test:house_t", //结构的路径(必填)
"weight": 1, //结构的随机权重(必填)
"match_terrain" : false //此结构是否贴地面类似村庄的道路选填默认值为false如为true则大型结构特征生成规则中height必须为"variable.height"才可生效)
},
{
...
}
],
"end_pool":"minecraft:empty" //终结池的identifier当大型结构递归到最大深度时将从终结池中选取结构进行拼接例如村庄道路的尽头选填默认值为"minecraft:empty"
}
}
```
> 开发者可以在编辑器中创建和编辑结构池配置,如下图:
![图片](./picture/structurepool.png)
#### 1-4-3.大型结构特征生成规则配置:
简介:大型结构特征生成规则配置主要用于规定大型结构的初始摆放位置
举例:原版村庄生成时候先生成村庄中心,根据中心向四周伸展生成道路以及其他房屋等,此配置可理解为村庄中心摆放规则
```json
{
"format_version": "1.14.0",
"netease:large_feature_rules": {
"description": {
"identifier": "netease:large_feature_test", //大型结构摆放规则identifier必填
"place_pool": "netease:centerPool" //结构池的identifier必填
},
"allowed_biomes":[ //允许产生的群系(群系的tag)(必填)
"plains",
"desert",
"ocean"
],
"town_spacing":8, //间隔距离比如8则 8 * 8个区块的正方形内选择一个点摆放必填
"min_town_separation":1, //距离边缘距离比如1则在8 * 8个区块的正方形内圈出6 * 6的正方形并在正方形内部选取一个点进行摆放必填
"max_depth": 8, //递归深度越多,生成的结构越多,比如村庄的道路,调高之后,村庄道路变长(必填)
"height" : 100, //中心结构的生成高度(选填,默认值为"variable.height"
"ignore_fit_in_context" : false, //允许生成过结构的地方是否可以继续生成结构选填默认值为false
"center_pool_rotation" : [0] //允许中心结构旋转的角度数组内数字仅支持0、90、180、270选填默认值为[0, 90, 180, 270]
}
}
```
"height"中可使用以下variable属性
| 变量 | 解释 |
| --------------- | --------------------------- |
| variable.worldx | 实际位置的x轴的实际坐标 |
| variable.worldz | 实际位置的z轴的实际坐标 |
| variable.height | 实际位置最高非空气方块y坐标 |
**注2.9版本后大型结构支持在末地和下界摆放在下界中variable.height是一个固定值128最高非空气方块**
"height"中可使用以下query属性
| 变量 | 解释 |
| ----------- | ------------------------------------------------------------ |
| query.noise | 用于产生伪随机数,传入两个数,返回一个 -1~1 之间的浮点数。当传入的两个参数相同时query.noise得到的结果也相同。 |
> 开发者可以在编辑器中创建和编辑大型特征生成规则配置,如下图:
![图片](./picture/largefeature.png)
## 2.demo解释
- dm1010维度
- 使用大型结构特征规则在高度100生成许多大型结构
![image-20230419173951601](./picture/mcstudio_11.png)
- demo获取途径内容库→作品模板→搜索**自定义地形特征**
![image-20230525105655400](./picture/mcstudio_12.png)
## 3.参考
拼图方块Wiki[https://zh.minecraft.wiki/w/%E6%8B%BC%E5%9B%BE%E6%96%B9%E5%9D%97](https://zh.minecraft.wiki/w/%E6%8B%BC%E5%9B%BE%E6%96%B9%E5%9D%97)
## 4.常见问题or报错
1.This code should only be executed on the main or server thread
原因:一般情况下是结构(structure)中使用了命令方块并且命令方块中使用一些fillreplace等对区块操作的指令因为类似前面这些指令只能对已经加载完成的区块进行操作而大型结构加载时区块并未加载完全所以出现此Assert
建议开发者可在结构中放置BlockEntity并在脚本中监听tick事件当玩家靠近时完成类似命令方块中的操作即可
![image-20230905171751131](./picture/large_feature_bug_picture1.png)
2.当使用**ignore_fit_in_context**字段并使用拼图方块在一个结构的内部生成另外一个结构时,可能会出现内部结构缺失的问题
正常情况如下图(中间钻石地板通过房子内拼图方块生成):
![image-20231020145606031](./picture/qa_image1.png)
异常情况(房子内的钻石地板被裁剪掉了):
![image-20231020145736717](./picture/qa_image2.png)
出现此问题的原因是Minecraft区块加载顺序是不固定的当大型结构生成时候会判断结构的生成范围是否与这个区块有交集如果有则执行一遍完整的结构摆放可能出现两种情况
1.假设房子和内部钻石地板都没有跨区块,先生成房子,再生成钻石地板,这样是正常的
2.假设房子跨区块,但是钻石地板没有跨区块,并且钻石地板所在区块优先生成时,后续和房子有交集但和钻石地板没交集的区块会再执行一遍房子的摆放逻辑,所以就会将原来的钻石地板给裁剪,造成了异常
解决方案:
1.可以考虑加大内部结构导出时候的Size即导出时候框选的大小至少让这个size比外面房子的要大即可解决被裁剪的问题
![image-20231020152452235](./picture/qa_image3.png)
2.但是将内部结构Size调大会导出许多空气导致生成时外部房子被裁剪可以考虑将空气替换为结构空位来解决
![image-20231020152900009](./picture/qa_image4.png)
![image-20231020153257466](./picture/qa_image5.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB