保存数据

保存数据

保存数据(Saved Data,简称 SD)系统是维度能力(level capabilities)的替代方案,可以按维度附加数据。

SavedData 按维度存储示意:ServerLevel 取得 DimensionDataStorage,加载或创建 SavedData;修改数据后调用 setDirty,后续保存阶段写出 NBT 到维度 data 文件夹中的 .dat 文件。

原创说明图,依据 Forge 1.21.x 官方文档 绘制。

声明

每个 SD 实现都必须继承 SavedData 类。需要注意两个重要方法:

  • save:让实现将 NBT 数据写入维度。
  • setDirty:修改数据后必须调用此方法,通知游戏有需要写入的更改。如果不调用,#save 就不会被调用,原有数据会保留。

附加到维度

SavedData 会动态加载和/或附加到维度。因此,如果从未在某个维度上创建它,它就不存在。

SavedData 由 DimensionDataStorage 创建和加载;可通过 ServerChunkCache#getDataStorage 或 ServerLevel#getDataStorage 获取它。然后调用 DimensionDataStorage#computeIfAbsent,取得或创建 SD 实例。该方法会尝试获取已有实例;如果不存在,就创建新实例并加载所有可用数据。

DimensionDataStorage#computeIfAbsent 接受三个参数:将 NBT 数据加载到 SD 并返回该实例的函数、构造新 SD 实例的 supplier,以及对应维度的 data 文件夹中 .dat 文件的名称。

例如,如果下界中的 SD 名为“example”,就会创建 ./<level_folder>/DIM-1/data/example.dat,实现如下:

// 在某个类中
public ExampleSavedData create() {
  return new ExampleSavedData();
}

public ExampleSavedData load(CompoundTag tag) {
  ExampleSavedData data = this.create();
  // 加载保存的数据
  return data;
}

// 在该类的某个方法中
netherDataStorage.computeIfAbsent(this::load, this::create, "example");

要在多个维度之间持久保存 SD,应将它附加到主世界,可通过 MinecraftServer#overworld 获取主世界。主世界是唯一永远不会完全卸载的维度,因此非常适合存储跨维度数据。

原文:Saved Data。