蓝图格式

Schematica 的蓝图文件(默认扩展名 .schematic)是 NBT 格式,可存方块、元数据、TileEntity 与实体。本条目记录其结构与两种格式的差异。

两种格式

格式 开关 说明
标准 MCEdit / Forge schematic useSchematicplusFormat = false(默认) 常规格式,方块 ID 空间受 4096 限制
schemplus(.schmplus) useSchematicplusFormat = true 支持远高于 4096 的方块 ID 数,用于 ID 空间被大量 mod 撑爆的整合包

⚠️ 切换不是双向兼容的。配置项描述明确写 “Only schematics in schemplus format will be loaded”——开启 schemplus 后只加载 schemplus 文件,此前保存的标准格式蓝图会被静默忽略。切换前需自行转换或重新保存。

实现类在 world/schematic/:SchematicFormat(格式判定)、SchematicUtil(读写工具)、SchematicAlpha(透明投影数据)、UnsupportedFormatException。

蓝图数据结构

world/storage/Schematic.java 实现 api/ISchematic:

方法 说明
setBlock(x, y, z, block, metadata) 写入方块 + 元数据
getBlockMetadata(x, y, z) 读元数据
setTileEntity(x, y, z, tileEntity) 写入 TileEntity
setIcon(ItemStack) 设置 GUI 列表里显示的图标
getWidth() / getLength() / getHeight() 三轴尺寸

三轴尺寸上限:CommonProxy.saveSchematic(CommonProxy.java:193-195)用 short 存尺寸:

final short width  = (short) (Math.abs(maxX - minX) + 1);
final short height = (short) (Math.abs(maxY - minY) + 1);
final short length = (short) (Math.abs(maxZ - minZ) + 1);

即单轴最大 32,767 方块。更大的区域会整数溢出变成负数,进而让尺寸计算错误。

保存流程

copyChunkToSchematic(CommonProxy.java:112-169)逐方块复制:

  1. 按区块边界裁剪出 localMinX/localMaxX/localMinZ/localMaxZ;
  2. 三重循环 chunkLocalX × y × chunkLocalZ,逐方块 world.getBlock + getBlockMetadata;
  3. block.hasTileEntity(metadata) 为真时,走 NBTHelper.reloadTileEntity 转换坐标后写入;
  4. 转换抛 NBTConversionException 时写入 Blocks.bedrock 并继续;
  5. 最后用 getEntitiesWithinAABB 抓取区域内全部实体,NBTHelper.reloadEntity 后 addEntity。

保存本身是分帧异步的:QueueTickHandler.INSTANCE.queueSchematic(container) 把任务入队,避免一次性卡死。

NBT 转换

nbt/ 包 3 个类:

类 作用
NBTHelper 方块 / TileEntity / 实体的 NBT 读写与坐标重定位
NBTConversionException 转换失败异常
ForgeMultipart postInit 时 ForgeMultipart.init(),处理 Forge 多方块(multipart)方块的 NBT

最后一项是 GTNH 的关键:GT 系列大量使用 multipart 方块,若无此处理则保存的机器会丢失整块结构。

存储位置

路径 内容
<数据目录>/schematics 全部本地蓝图(SCHEMATIC_DIRECTORY_STR = "schematics")
<数据目录>/schematics/<玩家名>/ 玩家私有蓝图(服务器配额目录)

文件名支持 图标名;文件名 语法(CommonProxy.java:177-181),分号前段被 SchematicUtil.getIconFromName 用作列表图标。

已知缺陷

  • TileEntity 失败静默变基岩。CommonProxy.java:141-145 捕获 NBTConversionException 后执行 schematic.setBlock(localX, localY, localZ, Blocks.bedrock),玩家在保存含异常 TileEntity 的机器时会得到基岩块,聊天栏无任何提示(仅 log 记 error)。这是最容易被误认为「mod bug」的行为。

  • short 存尺寸无溢出保护。单轴 > 32,767 时 (short) 强转溢出为负数,getWidth() 等返回错误值,后续加载会失败或错位。

  • extraAirBlocks 影响渲染但不影响数据。该配置让渲染器把某些方块当空气画(用于 GT 的 placeholder 方块),蓝图文件里的数据不变。换机器加载同一蓝图时若 extraAirBlocks 不同,显示效果会不同。

  • 玩家配额按目录总字节数算。ServerProxy.java:56-66 用 spaceUsed / 1024 > playerQuotaKilobytes 判定,默认 8192 KB(8 MB)。这是总量上限而非单文件上限,且删除蓝图后需文件系统真正释放空间才回落。

相关条目

  • 配置 - useSchematicplusFormat 与 extraAirBlocks 的完整说明
  • 指令 - 保存 / 列出 / 删除服务器蓝图