Auf Englisch lesen

Freigeben über


Akteurspeicher in Minecraft: Bedrock Edition

Minecraft hat zahlreiche Drittanbieter dazu inspiriert, nützliche Tools zum Anzeigen und Bearbeiten von Weltdateien zu entwickeln, die außerhalb des Clients existieren. Tools wie der Universal Minecraft Editor und MCEdit sind in der Community sehr beliebt und setzen voraus, dass man weiß, wo die einzelnen Daten jedes Levels in den LevelDB-Dateien auf der Festplatte zu finden sind. Mit dem Upgrade vom älteren Akteurspeicher zum modernen Akteurspeicher in Version 1.18.3 haben sich die Speicherorte für die Akteurdaten in den LevelDB-Dateien geändert. Dies müssen die externen Entwickler wissen.

Wie sahen die früheren Akteurdaten aus?

Vor Version 1.18.3 wurden die Akteurdaten pro Chunk als Blob aller Akteure in diesem Chunk gespeichert. Dies bedeutete bei jeder Änderung eines einzelnen Akteurs Folgendes:

  • Erfassung der Daten von jedem einzelnen Akteur im Chunk
  • Anhängen der Daten für jeden Akteur in einem einzelnen Puffer/Blob
  • Schreiben dieser gruppierten Daten in den Chunk

Warum verschieben wir die Akteurdaten?

Beim früheren Format für die Speicherung von Akteurdaten mussten bei der Änderung eines Akteurs in einem Chunk immer alle gespeichert werden, auch wenn sich nur einer tatsächlich geändert hatte. Dies führte zu vielen unnötigen Operationen und machte die Übertragung von Objekten zwischen Chunks zu einem teuren und anfälligen System.

Wie werden moderne Akteurdaten auf der Festplatte gespeichert?

Der moderne Akteurspeicher speichert jeden Akteur unter einem eindeutigen individuellen LevelDB-Schlüssel. Dies ermöglicht Speicheroperationen für einzelne Akteure. Darüber hinaus bedeutet es, dass es kein Schlüssel-Wert-Paar für alle Akteure in einem Chunk gibt. Tatsächlich sind die Schlüssel der einzelnen Akteure in einem eigenen Schlüsselbereich vom Rest der Chunk-Daten getrennt und Chunks haben keine Daten auf der Festplatte, die sich direkt auf die in ihnen enthaltenen Akteure beziehen.

Stattdessen verwenden wir Daten vom Chunk, um deterministisch einen eindeutigen Schlüssel für den Chunk zu generieren, in dem wir einen Hashwert der LevelDB-Schlüssel für die Akteure im Chunk speichern. Diese Hashwerte sind ebenfalls von den nicht akteurbezogenen Chunk-Daten und dem Schlüsselbereich für den Akteur getrennt.

Sehen wir uns an, wie dies auf der Festplatte angezeigt wird:

LevelBD-Diagramm mit dem Schlüsselbereich für den Chunk, dem Schlüsselbereich für den Akteur-Hashwert und dem Schlüsselbereich für den Akteur

Schlüsselbereich für den Chunk

Links im Diagramm sehen wir den Schlüsselbereich für den Chunk. Diese Schlüssel weisen das Format der alten Chunk-Schlüssel auf: <Chunk Position><DimensionID>. Es gibt ein sehr altes Chunk-Format, in dem es keine Dimensions-ID gibt. Daher ist es möglich, eine sehr alte Welt zu laden, in der Chunk-Schlüssel keine Dimensions-ID aufweisen. Sie werden unter einem neuen Schlüssel mit der Dimensions-ID gespeichert. Dies ist ein altes Verhalten, das noch immer existiert.

Dies sind die kleinsten Schlüssel, die durch Zusammenschieben auf der Festplatte verwendet werden. Der Chunk-Schlüssel wird als Präfix für Schlüssel verwendet, die alle nicht akteurbezogenen Daten aus dem Chunk speichern. Jede Art von Daten aus dem Chunk weist ihre eigene Schlüssel-ID auf, die an das Präfix des Chunk-Schlüssels angehängt wird.

Chunk-Schlüssel-IDs für nicht akteurbezogene Daten


enum class LevelChunkTag : char {
  Data3D = 43,
  Version, // This was moved to the front as needed for the extended heights feature. Old chunks will not have this data.
  Data2D,
  Data2DLegacy,
  SubChunkPrefix,
  LegacyTerrain,
  BlockEntity,
  Entity, // Legacy actor storage which will be deleted from LevelDB upon upgrading the chunk to use modern actor storage
  PendingTicks,
  LegacyBlockExtraData,
  BiomeState,
  FinalizedState,
  ConversionData, // Data that the converter provides that are used at runtime for things like blending
  BorderBlocks,
  HardcodedSpawners,
  RandomTicks,
  CheckSums,
  GenerationSeed,
  GeneratedPreCavesAndCliffsBlending,
  BlendingBiomeHeight,
  LegacyVersion = 118
};

Schlüsselbereich für den Akteur-Hashwert

In der Mitte sehen wir den Schlüsselbereich für den Hashwert. Jeder Hashwert-Schlüssel weist das Format dg<Chunk Key> auf.

  • dg ist ein hartkodiertes Präfix für alle Hashwert-Schlüssel. Dadurch wird erzwungen, dass alle Hashwerte auf der Festplatte zusammenhängend sind, und die Größe aller Hashwert-Schlüssel wird derart erhöht, dass sie in der LevelDB vor den nicht akteurbezogenen Chunk-Daten platziert werden.

  • <Chunk Key> ist die gleiche Schlüsselzeichenfolge, die von dem Chunk verwenden wird, mit dem die Daten verknüpft sind.

Schlüsselbereich für den Akteur

Rechts sehen wir den Schlüsselbereich für den Akteur. Jeder Akteurschlüssel weist das Format actorpref<ActorUniqueID> auf.

  • actorpref ist ein hartkodiertes Präfix für alle Akteurschlüssel. Dadurch wird erzwungen, dass alle Akteurdaten auf der Festplatte zusammenhängend sind, und die Größe aller Akteurschlüssel wird derart erhöht, dass sie in der LevelDB vor den nicht akteurbezogenen Chunk-Daten und allen Hashwerten platziert werden.

  • <ActorUniqueID> ist eine eindeutige ID, die für jeden Akteur generiert wird, wenn er dem Level hinzugefügt wird. Diese ID ist zwischen Spielsitzungen einheitlich und nur für diese Welt eindeutig. Andere Akteure in anderen Welten haben möglicherweise die gleiche ID, es hat jedoch kein Akteur in derselben Welt die gleiche ID.