SaveSection3D(三维存档区)
基本信息
| 属性 | 值 |
|---|---|
| 实现类 | cubicchunks.regionlib.impl.save.SaveSection3D |
| 继承 | SaveSection<SaveSection3D, EntryLocation3D> |
| key 类型 | EntryLocation3D(实现 IKey<EntryLocation3D>) |
| 每区域条目数 | ENTRIES_PER_REGION = (1 << 4) * (1 << 4) * (1 << 4) = 4096 |
| 区域文件名 | <regX>.<regY>.<regZ>.3dr |
| 目录 | SaveCubeColumns.create() 里固定为 <directory>/region3d |
| 扇区大小 | 512(SimpleRegionFactory.createDefault(..., 512)) |
⚠️ 这不是一个 Minecraft 维度。 本 mod 没有
WorldProvider/DimensionType/registerDimension。“3D"指存档数据空间是三维的(X/Y/Z 三个坐标轴,对应 Cubic Chunks 的"立方体 cube”),是为三维世界准备的分区方式,与下界/末地等游戏维度无关。
坐标 ↔ 区域 / id 的换算
private static final int LOC_BITS = 4; // 16
private static final int LOC_BITMASK = (1 << 4) - 1; // 15
public static final int ENTRIES_PER_REGION = 4096;
getRegionKey() → new RegionKey(regX + "." + regY + "." + regZ + ".3dr") // 各自 >> 4
getId() → ((entryX & 15) << 8) | ((entryY & 15) << 4) | (entryZ & 15)
| 性质 | 说明 |
|---|---|
equals |
比较 entryX / entryY / entryZ 三字段 |
hashCode |
31 * (31 * entryX + entryY) + entryZ |
| 字段访问 | getEntryX() / getEntryY() / getEntryZ() |
toString |
EntryLocation3D{entryX=…, entryY=…, entryZ=…} |
| 可变性 | 三字段均 final |
注意 2D / 3D 的粒度差 2 倍:2D 每区域 32×32(LOC_BITS = 5),3D 每区域 16×16×16(LOC_BITS = 4)。同为 X/Z 轴,2D 的区域边长是 3D 的两倍。
EntryLocation3D.Provider
| 方法 | 行为 |
|---|---|
getKeyCount(RegionKey) |
恒返回 ENTRIES_PER_REGION = 4096 |
isValid(RegionKey) |
key.getName().matches("-?\\d+\\.-?\\d+\\.-?\\d+\\.3dr") |
fromRegionAndId(RegionKey, int) |
先 isValid,不通过抛 IllegalArgumentException("Invalid name " + regionKey.getName());relativeX = id >>> 8、relativeY = (id >>> 4) & 15、relativeZ = id & 15,还原为 new EntryLocation3D(regX << 4 | relativeX, regY << 4 | relativeY, regZ << 4 | relativeZ) |
构造与工厂
| 签名 | 说明 |
|---|---|
SaveSection3D(IRegionProvider<EntryLocation3D>... regionProvider) |
只有变参构造(super(Arrays.asList(regionProvider)))。与 SaveSection2D 不同,3D 版没有单 IRegionProvider 的便捷构造 |
static SaveSection3D createAt(Path directory) |
标准两层回退装配 |
createAt(Path):
| 顺序 | IRegionProvider |
底层 IRegion |
存在判定 |
|---|---|---|---|
| 1 | SharedCachedRegionProvider(SimpleRegionFactory.createDefault(new EntryLocation3D.Provider(), directory, 512)) |
Region(512 B 扇区) |
Files.exists(directory.resolve(key.getName())) |
| 2 | SharedCachedRegionProvider(new SimpleRegionFactory<>(new EntryLocation3D.Provider(), directory, (kp, rk) -> new ExtRegion<>(directory, Collections.emptyList(), kp, rk), (kp, rk) -> Files.exists(directory.resolve(rk.getName() + ".ext")))) |
ExtRegion(.ext 目录) |
Files.exists(dir/<name>.ext) |
两层的 keyProvider 都是 new EntryLocation3D.Provider(),扇区表能对上同一个 id 空间——这正是回退链能透明工作的前提。
数据访问
与 SaveSection2D 一样,SaveSection3D 本身不覆写任何数据方法。SaveCubeColumns 的对应入口:
| 方法 | 签名 |
|---|---|
| 单条写 | save3d(EntryLocation3D location, ByteBuffer data) |
| 批量写 | save3d(Map<EntryLocation3D, ByteBuffer> entries) |
| 单条读 | load(EntryLocation3D location, boolean createRegion) → Optional<ByteBuffer> |
| 批量读 | load3D(Collection<EntryLocation3D> positions, boolean createRegion) → BatchReadResult<EntryLocation3D> |
| 取本节 | getSaveSection3D() |
SaveCubeColumns.flush() / close() 会依次转发到 saveSection2D 和 saveSection3D。
数值
| 数值 | 值 |
|---|---|
| 单区域条目数 | 4096 |
| 单条目字节上限 | 130556(255 × 512 − 4);超出自动落 .ext |
| 单区域头表扇区数 | 4096 × 4 = 16384 字节 = 32 扇区,开局即占用 |
对比:2D 版头表只要 8 扇区,3D 版要 32 扇区——3D 每个区域文件开头的固定开销是 2D 的四倍。
相关条目
- 存档目录与文件命名 -
region3d/<X>.<Y>.<Z>.3dr - 多提供者回退链
- 区域文件格式
- SaveSection2D - 同构的二维版本