本篇教程的视频:

本篇教程源代码

GitHub地址:TutorialMod-Structure-1.21

介绍

本篇教程我们将为我们的模组添加自定义结构,结构在高版本中现在也是一个数据驱动的东西了,所以说除了结构文件之外,其他的文件都是json文件

然后关于结构的教程也有Click Here

这个作者写的是StructureTutorialMod,这个模组是专门用来讲解结构的,大家可以去看看,虽然是英文的,但是也是很详细的,这里我就不再赘述了

这里面也分单体结构(只有一个小建筑体)和多体结构(由两个及其以上的建筑体组合而成),本篇教程我们将讲解单体结构

准备工作

首先得有一个结构文件,这个文件是nbt文件

但我们怎么获取呢?

首先当然得有个建筑(或者结构),你先造个小东西,这里先不要超过48*48*48,因为这个是结构方块最大的囊括范围,也是一个单体建筑最大的范围

然后我们要获取一个结构方块,这里我们只能使用命令来获取,因为结构方块是没有物品的,所以我们得用命令来获取

1
/give @s minecraft:structure_block

随后,我们将一个结构方块放在我们的建筑的一个角落,然后我们打开它,设置为Corner角落模式),设置好结构的名字

而后我们跑到对角线的位置放置另一个结构方块,设置为Save储存模式),也设置好相同的名字

接下来我们在这个结构方块中点击Detect检测),然后它就会出现一个白框包起来的区域,这个就是我们的结构将会被保存的区域,这里我们先观察一下我们的建筑体是否完全在这个白框内,如果不在,我们可以调整一下

然后我们点击Save保存),这个时候我们的结构就被保存了,我们可以在world文件夹下的generated文件夹中找到一个structures文件夹,里面就是我们的结构文件

不过,除此之外,我再讲讲另外的几个方块

这里我们先将结构方块显示不可见方块设置为ON,然后我们就可以在白框内看到一些紫色的小方块,这些小方块就代表空气

这里我们先获取一些方块

1
2
3
4
5
/give @s minecraft:structure_void

/give @s minecraft:barrier

/give @s minecraft:light

第一个是结构空位,这个是用来填充结构的

我们现在看到的都是紫色的小方块,它们在世界生成中就直接是空气

如果说我们的结构生成在水中,那么这些紫色小方块的位置还是空气,不会被水填充(除了水会流下了)

而我们使用获得的结构空位,右键这些紫色小方块,小方块会变成粉色的(可能颜色很淡,不太明显)

此时,如果说我们的下来的结构生成在水中,那么这些粉色小方块的位置就会被水填充

第二个是屏障,这个是用来阻挡玩家的,但是不会阻挡光线,这个我就不用多说了,右键后,紫色小方块会变成红色

第三个是光源方块,这个是用来照亮的,右键后,紫色小方块会变成黄色的,同时它的亮度默认是15,也就是最大亮度,右键可以改变其亮度

光源方块有一个好处,对于大场景或是不太好放置光源的地方,我们可以使用光源方块来照亮(这也是未来罗德岛陆行舰3.0工程中即将大规模运用的一个东西)

编写结构相关数据文件

移动结构文件

我们先将保存的nbt文件放到resources/data/tutorialmod/structure(注意没有s)文件夹下

tags

structure的同级目录下,我们再创建一个tags文件夹,里面再创建一系列文件夹,tags/worldgen/biome/has_structure,然后在里面创建一个house.json文件(具体的名字和你的保存的结构的nbt文件一致)

结构如下

1
2
3
4
5
6
7
8
resources
├── data
│ └── tutorialmod
│ └── tags
│ └── worldgen
│ └── biome
│ └── has_structure
│ └── house.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"replace": false,

"_comment": " This biome tag can specify the biome directly. Or specify another biome tag by starting with # ",
"values": [
"#minecraft:is_jungle",
"#minecraft:is_forest",
"#minecraft:is_taiga",
"minecraft:desert",
"minecraft:plains",
"minecraft:snowy_plains",
"minecraft:sunflower_plains",
"minecraft:savanna",
"minecraft:savanna_plateau",
"minecraft:windswept_savanna"
]
}

这个是指我们的结构可以生成在哪些生物群系中,这里我们指定了一些生物群系,当然你也可以指定其他的生物群系

worldgen

structure的同级目录下,我们再创建一个worldgen文件夹,里面再创建一系列文件夹,结构如下

1
2
3
4
5
6
7
resources
├── data
│ └── tutorialmod
│ └── worldgen
│ └── structure
│ └── structure_set
│ └── template_pool

稍微有点多,名字一定一定不能错

structure

在个文件夹下,我们创建一个house.json文件(具体的名字和你的保存的结构的nbt文件一致)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
// The base structure class to use for the behavior of the structure. (Like extra terrain checks and such)
"type": "minecraft:jigsaw",

// the path to the template pool json file to use
"start_pool": "tutorialmod:start_pool",

// This is how many pieces away from the starting piece a piece of the structure can spawn
// Think of it like the length of the branch of the structure
"size": 1,

// Maximum distance away from center that pieces can spawn. Cannot be greater than 128
"max_distance_from_center": 80,

// The biome tag to use for what biomes that this structure can spawn in"
"biomes": "#tutorialmod:has_structure/house",

// The generation step for when to generate the structure. there are 10 stages you can pick from!
// This surface structure stage places the structure before plants and ores are generated
// See GenerationStep.Feature enum for all the stages you can use and what order they are in
"step": "surface_structures",

// Where to spawn our structure at what y value if project_start_to_heightmap is not present.
// start_height can be used to spawn at a random fixed y value by doing something like: "max_inclusive": { "below_top": 10 }, "min_inclusive": { "above_bottom": 32 }
// If project_start_to_heightmap is present, the y value chosen in start_height will be added to the terrain's y value.
// So a start height that gives -5 will sink the structure 5 blocks into the terrain. Here, we will spawn this structure 60 blocks above the terrain.
"start_height": {
"absolute": 0
},

// Makes our sky fan structure take the terrain's top y value and add it to the start_height y value above.
// The final value is the y value the structures spawn at.
// WORLD_SURFACE_WG will stop at first non-air block so it spawns above oceans always instead of sunken into a deep sea.
"project_start_to_heightmap": "WORLD_SURFACE_WG",

// Keep this false. This is only for vanilla legacy villages to make it spawn properly. We don't need no hacks here!
"use_expansion_hack": false,

// What mobs can spawn over time in the structure.
// Make sure you add the mob to the right category (monster, creature, etc)
"spawn_overrides": {
"creature": {
"bounding_box": "piece",
"spawns": [
{
"type": "minecraft:evoker",
"weight": 5,
"minCount": 1,
"maxCount": 2
},
{
"type": "minecraft:phantom",
"weight": 1,
"minCount": 1,
"maxCount": 1
}
]
}
}
}

这里面大部分是注释,可以自己先看看

type是结构的类型,这里我们使用jigsaw,这个是用来生成结构的;start_pool是结构的模板池

size是结构生成数量;max_distance_from_center是结构离中央区块的最大生成距离

biomes是结构的生物群系,指定为我们刚才写的;step是结构的生成位置

start_height是结构的生成高度,0就是贴地;project_start_to_heightmap是结构按地形投影的高度

use_expansion_hack这玩意适用于旧版村庄生成,不管他;spawn_overrides是结构的生成生物什么的

template_pool

接下来我们在template_pool文件夹下创建一个start_pool.json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
// More info on template pools can be found here: https://minecraft.gamepedia.com/Custom_world_generation#JSON_format_8
// Yes, worldgen json files can have comments. Minecraft does "lenient" parsing of these json files.

// This is the name of the template pool itself. I tend to just put the file path and file name here with modid.
"name": "tutorialmod:start_pool",

// The template pool to refer to if the entries in 'elements' fails to generate.
"fallback": "minecraft:empty",

// Here you can list as many nbt files or placed features to spawn.
// Do note that placed features needs a special element entry stuff.
"elements": [
{

// How likely out of all the element for this one to be chosen.
"weight": 1,
"element": {

// The Identifier of the nbt file itself of the structure piece.
// Note, this will automatically check into the 'structures' folder for the nbt file.
// The final path would look like 'resources/data/mccourse/structures/kaupen_house.nbt'
// The Jigsaw block in the structure will point to side_pool.json to spawn the other half of the house.
"location": "tutorialmod:house",

// Processor JSON files can be used to randomize or replace blocks dynamically. Here, we don't do any of that.
"processors": "minecraft:empty",

// If set to 'terrain_matching', the house would be deformed to fit the change in land.
// That's best for roads so lets stay 'rigid' for now.
"projection": "rigid",

// The kind of element we are spawning. This one is most likely what you want.
// There's 'minecraft:legacy_single_pool_element' but that swaps the behavior of
// Air and Structure Void in your piece as well as change the attachment mechanism.
// It's only for old Vanilla Jigsaw Structures so don't use it. Stick with non-legacy.
"element_type": "minecraft:single_pool_element"
}
}
]
}

这个文件是模板池,里面是结构的生成模板

大体上不用改什么,改个namelocation就行了

structure_set

structure_set文件夹下创建一个house.json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
// What structures to pick to try and spawn if a spot passes the placement check.
// If two or more structures in this list can spawn in a biome at a spot, a random one based on weight is chosen to spawn
"structures": [
{
"structure": "tutorialmod:house",
"weight": 1
}
],
"placement": {
// Make sure this is unique and does not match any other structure set's salt
"salt": 564604120,

// The average distance apart in chunks for spawn attempts
"spacing": 20,

// Minimum distance apart in chunks for spawn attempts
// MUST ALWAYS BE SMALLER THAN spacing ABOVE
"separation": 6,

// The kind of placement to use. The other kind is ring based like strongholds use.
"type": "minecraft:random_spread"
}
}

这是结构的生成设置,改个structure就行了

当然,这里的salt是每一个结构都有且唯一的,不要和其他的结构的salt一样(这玩意我也不知道是什么,从Wiki上找找直接去密码学里了)

那么现在,我们的文件都写完了,我们可以开始游戏了,当然,建议新建一个存档