10 KiB
此文档译自https://wiki.bedrock.dev/nbt/mcstructure.html
.MCSTRUCTURE
文件结构
mcstructure 文件是未经压缩的 NBT 文件,也正如《我的世界:基岩版》的所有 NBT 文件一样,其皆以小端字节序(又称小端序)存储。以下是此类文件的 NBT 标签结构:
-
列表
block_indices
: 结构中存储的方块索引。包含两个列表,第一个为实际方块数据,第二个列表对应第一个列表中的方块之内含层(second layer)的方块数据。每一个方块都以一个整型数据,即在方块池(palette)(详见下文)中的索引下标(index),的形式存储。方块的存储是一维列表,将结构中每个方块依照从 Z 轴到 Y 轴到 X 轴且沿轴正方向的顺序一字排开形成列表。例如,若结构大小为[2,3,4]
,则每一层(即包括内含层也是一样的顺序)的24个方块(这个数量是由结构大小决定的,即结构尺寸的乘积)分别对应着如下相对坐标位置的方块:[(0,0,0), (0,0,1), (0,0,2), (0,0,3), (0,1,0), (0,1,1), (0,1,2), (0,1,3), (0,2,0), (0,2,1), (0,2,2), (0,2,3), (1,0,0), (1,0,1), (1,0,2), (1,0,3), (1,1,0), (1,1,1), (1,1,2), (1,1,3), (1,2,0), (1,2,1), (1,2,2), (1,2,3)]
。若索引下标为-1
则表示此处无方块(即对应“结构空位”),则此处在结构加载时就会保留其原有方块。在我们用结构方块保存结构时这种现象会发生,同时方块的内含层中也大多是无方块的。同时,两个层的方块共享一个方块池 -
of
复合列表
entities
: 以 NBT 存储的实体列表,其存储格式与在地图文件中存储实体的形式一致。类似Pos
与UniqueID
这样的独立于不同世界中的标签亦会被保存下来,但是《我的世界》加载这样的标签时会将它们覆写为实际值 -
复合
palette
: 理论上可以包含多种不同名字的方块池(palette),似乎这样设计是可能要支持以后的对于同一种结构的变体形态。但可惜的是,目前游戏内仅保存和加载名称为default
的方块池
列表
structure_world_origin
: 结构最初保存时的起始点坐标(position),以三个整型(integer)组成的列表的形式出现。坐标的值即结构方块保存时的坐标加上我们在结构放开里填写的偏移数据。这个坐标用于计算(determine)加载时实体的位置。一个实体的新的绝对坐标由其原始坐标减去结构最初保存时的起始点坐标后,再加上加载起始点的坐标计算而来。
以下是一些例子(以Python的数据结构为例):
# 大小为 1x3x1 (XYZ) 的
# 从下往上分别是一个指令方块、一个铁块和一个空气方块的
# 结构 NBT 数据
{
'format_version': TAG_Int(1, 'format_version'),
'size': [TAG_Int(1, None), TAG_Int(3, None), TAG_Int(1, None)],
'structure': {
'block_indices': [
[TAG_Int(0, None), TAG_Int(1, None), TAG_Int(2, None)],
[TAG_Int(-1, None), TAG_Int(-1, None), TAG_Int(-1, None)]
],
'entities': [],
'palette': {
'default': {
'block_palette': [
{
'name': TAG_String('minecraft:command_block', 'name'),
'states': {
'conditional_bit': TAG_Byte(0, 'conditional_bit'),
'facing_direction': TAG_Int(1, 'facing_direction')
},
'version': TAG_Int(17959425, 'version')
},
{
'name': TAG_String('minecraft:iron_block', 'name'),
'states': {},
'version': TAG_Int(17959425, 'version')
},
{
'name': TAG_String('minecraft:air', 'name'),
'states': {},
'version': TAG_Int(17959425, 'version')
}
],
'block_position_data': {
'0': {
'Command': TAG_String('help 4', 'Command'),
'CustomName': TAG_String('', 'CustomName'),
'ExecuteOnFirstTick': TAG_Byte(0, 'ExecuteOnFirstTick'),
'LPCommandMode': TAG_Int(0, 'LPCommandMode'),
'LPCondionalMode': TAG_Byte(0, 'LPCondionalMode'),
'LPRedstoneMode': TAG_Byte(0, 'LPRedstoneMode'),
'LastExecution': TAG_Long(0, 'LastExecution'),
'LastOutput': TAG_String('', 'LastOutput'),
'LastOutputParams': [],
'SuccessCount': TAG_Int(0, 'SuccessCount'),
'TickDelay': TAG_Int(0, 'TickDelay'),
'TrackOutput': TAG_Byte(1, 'TrackOutput'),
'Version': TAG_Int(25, 'Version'),
'auto': TAG_Byte(0, 'auto'),
'conditionMet': TAG_Byte(0, 'conditionMet'),
'conditionalMode': TAG_Byte(0, 'conditionalMode'),
'id': TAG_String('CommandBlock', 'id'),
'isMovable': TAG_Byte(1, 'isMovable'),
'powered': TAG_Byte(0, 'powered'),
'x': TAG_Int(1, 'x'),
'y': TAG_Int(1, 'y'),
'z': TAG_Int(1, 'z')
}
}
}
}
},
'structure_world_origin': [TAG_Int(0, None), TAG_Int(0, None), TAG_Int(0, None)],
}
# 大小为 2x2x2 (XYZ) 的
# 全是白色羊毛的
# 结构 NBT 数据
{
'format_version': TAG_Int(1, 'format_version'),
'size': [TAG_Int(2, None), TAG_Int(2, None), TAG_Int(2, None)],
'structure': {
'block_indices': [
[
TAG_Int(0, None),
TAG_Int(0, None),
TAG_Int(0, None),
TAG_Int(0, None),
TAG_Int(0, None),
TAG_Int(0, None),
TAG_Int(0, None),
TAG_Int(0, None)
],
[
TAG_Int(-1, None),
TAG_Int(-1, None),
TAG_Int(-1, None),
TAG_Int(-1, None),
TAG_Int(-1, None),
TAG_Int(-1, None),
TAG_Int(-1, None),
TAG_Int(-1, None)
]
],
'entities': [],
'palette': {
'default': {
'block_palette': [
{
'name': TAG_String('minecraft:wool', 'name'),
'states': {'color': TAG_String('white', 'color')},
'version': TAG_Int(17959425, 'version')
}
],
'block_position_data': {}
}
}
},
'structure_world_origin': [TAG_Int(0, None), TAG_Int(0, None), TAG_Int(0, None)]
}
源代码可参照此处,作者金羿。