结构 26.1 Fabric
本篇教程的视频
本篇教程的源代码
GitHub地址:
本篇教程目标
- 搞清结构由哪几个文件组成
- 学会用结构方块保存一个 nbt
- 学会写 structure / template_pool / structure_set / 群系标签 四份 json
- 知道每个参数调错了会有什么症状
介绍
村庄、遗迹、神殿,这些在游戏里都叫结构
结构比较特别的一点是:它是纯数据的,不用写一行代码
你只要准备好一个建筑,存成 nbt,再配四个 json,世界生成的时候就会把它摆进去
单体结构和多体结构
结构分两种
单体结构:一个 nbt,一摆就是一整栋,比如沙漠神殿、海底废墟的单个残骸
多体结构:很多 nbt 拼起来,靠「拼图方块」互相咬合,比如村庄、远古城市
这期我们做单体,也就是最简单的「一栋房子」
拼图那套东西复杂得多,等你单体玩明白了再往上走
准备工作:做一个 nbt
造一个房子
先在游戏里搭个小建筑,注意别超过 48×48×48
因为结构方块最大只能框这么大,这也是单体结构的上限
用结构方块保存
结构方块没有物品,只能打命令拿
1 | /give @s minecraft:structure_block |
用法是:在建筑的一个角放一个结构方块,切到 Corner(角落模式),填个名字(只能是小写字母和数字)
再到对角线的位置放第二个,切到 Save(保存模式),填同一个名字
点一下 Detect(检测),会出来一个白框,看看建筑是不是完整框住了
没问题就点 Save
保存之后,文件在存档目录下
1 | saves/<存档名>/generated/minecraft/structures/<名字>.nbt |
把这个文件拿走,就是我们需要的 nbt
三个小方块
保存的时候顺便认识三个东西,后面做结构很有用
结构空位(structure_void):白框里的紫色小方块就是它。它的意思是「这个位置是空气,而且生成的时候别被水填」
用结构空位右键紫色方块,会变成粉色,意思是「这个位置可以被水填」
屏障(barrier):看不见的墙,变身红色,用来挡住玩家
光源方块(light):变身黄色,用来打光,默认亮度 15,右键能调
做大场景的时候,光源方块比插火把方便多了
写数据文件
四份 json,路径一个都不能错
1 | src/main/resources/data/tutorial |
注意 structure 是单数,worldgen 下面那个也是单数
这两个地方最容易写错一个 s,然后游戏一点提示都没有,结构就是不生成
一、结构本身
data/tutorial/worldgen/structure/house.json
1 | { |
我们来逐一了解里面的参数
type是minecraft:jigsaw,看着奇怪,但单体结构也用它。原版还有desert_pyramid这种专用类型,那是硬编码的,我们用不了biomes指向群系标签,也就是tags里面的文件step是生成阶段,surface_structures是「地表结构」的生成阶段start_pool指向模板池,即template_pool里面的文件size是拼图的层数,单体结构给1就够start_height是高度偏移,0表示贴着地表project_start_to_heightmap是用哪张高度图对齐,WORLD_SURFACE_WG就是「最高的非空气方块」;这两个配合起来的意思是:找到地表高度,再加start_height,就是结构的落点use_expansion_hack是老版本村庄的兼容开关,我们给falsespawn_overrides是「结构内刷什么怪」,我们给空对象,表示用群系默认
二、模板池
data/tutorial/worldgen/template_pool/house/start_pool.json
1 | { |
模板池就是「候选建筑列表」
单体结构只有一个元素,所以 weight 随便写
其他参数:
location指向我们的结构nbt文件processors是方块替换规则(比如把石头换成苔石),minecraft:empty为空projection是贴合方式,rigid表示原样摆放,terrain_matching会跟着地形变形(生成道路、废弃建筑倒是可以用)element_type用single_pool_element,就是「一整个 nbt」
三、结构集
data/tutorial/worldgen/structure_set/houses.json
1 | { |
结构集决定「多久出现一次」
spacing是平均间隔,单位是区块,32就是平均每 32 个区块一个separation是最近间隔,8就是两个结构至少隔 8 个区块;注意,separation必须小于spacing,不然会崩salt是这张表的随机种子,每个结构集必须唯一,随手写个大数就行weight是「多个结构共用一个结构集时的权重」,我们只有一个,写1
四、群系标签
data/tutorial/tags/worldgen/biome/has_structure/house.json
1 | { |
这个标签决定「哪些群系能有这个结构」
可以直接写群系id(注意不要写错,其他模组的也是),也可以写 # 开头的群系标签,比如 #minecraft:is_forest 就把所有森林一网打尽
如果这里写的群系和 structure 里 biomes 指向的标签对不上,结构就是不会出现
测试
由于我们这篇教程是纯手写的,需要仔细检查,确认无误后,我们启动游戏进行测试
如果你写的这些文件有问题,要么世界里面找不到,要么点开新建世界界面就会直接崩溃
常见问题(大肥鱼总结版)
/locate说找不到结构:structure_set没写、salt和别的撞了,或者biomes标签里的群系你根本没遇到- 结构全埋在土里/悬空:调
start_height,负数往下沉、正数往上抬 - 结构一半卡在山坡里:把
project_start_to_heightmap改成WORLD_SURFACE_WG(默认就是),或者干脆选平原群系 - 结构完全不生成:
structure目录名写成了structures(多了个 s),或者worldgen下面也多了个 s - 启动直接崩,报
separation must be smaller than spacing:结构集里这两个数调反了 - 房子是破的、缺一块:保存 nbt 的时候白框没框全,回去重新
Detect一次 - 房子里灌满了水:nbt 里该用结构空位的地方用了空气,水就流进去了
- 结构互相叠在一起:
spacing太小,或者separation也太小 - 换了 nbt 但游戏里还是老的:
template_pool里location的名字没改,或者改了没重新打包 - 想让它只长在特定生物群系:改第四份文件的标签,别的都不用动







