本站文本内容除另有声明外,均在知识共享 署名-非商业性使用-相同方式共享 3.0 协议下提供。(详细信息…

携带版世界格式

来自Minecraft Wiki
跳转至: 导航搜索
此页面的(部分)内容需要被翻译。
你可以帮助我们来翻译此页面

Minecraft携带版为储存的世界使用了一个完全不同的格式。携带版0.9.0及以后版本采用的是谷歌LevelDB的修改版,使用Zlib压缩格式来储存资料。携带版0.8.1及更低版本使用一个经修改的NBT格式(为某些文件使用了小端序)。

1.0[编辑 | 编辑源代码]

1.0中,以LevelDB键值形式单独存储每个子区块。[1]

例如,主世界: | x: 32 | z: 32 | 标签: 8 |(非必须)子区块id: 8 |

任何其他维度: | x: 32 | z: 32 | 维度: 32 | 标签: 8 |(非必须)子区块id: 8 |

合理的标签值:

   enum class Tag : char {
       Data2D = 45,
       Data2DLegacy = 46,
       SubChunkPrefix = 47,
       LegacyTerrain = 48,
       BlockEntity = 49,
       Entity = 50,
       PendingTicks = 51,
       BlockExtraData = 52,
       BiomeState = 53,
       FinalizedState = 54,
       Version = 118
   };

要请求一个特定的子区块,你需要将值“47”填入标签中,并且提供一个介于0到16的数字给子区块ID。注意,子区块可以不存在。然而它们仍如同堆叠般运作,举例来说,如果有个子区块存在,那么所有其下方的子区块必须存在。

子区块的格式如下:

  • 版本:1字节
  • 方块ID:4kb,8比特每方块
  • 方块数据:2kb,4比特每方块
  • 天空亮度:2kb,4比特每方块
  • 方块亮度:2kb,4比特每方块

0.9.0[编辑 | 编辑源代码]

LevelDB 格式[编辑 | 编辑源代码]

Mojang修改的LevelDB已发布在 https://github.com/Mojang/leveldb-mcpe ,并且构建它需要的参数都被Tommaso记录于 https://twitter.com/_tomcc/status/477950809427427328 官方的LevelDB页面则位于 https://code.google.com/p/leveldb/ 寻找一个以携带版为基准的请参阅这里:https://github.com/tinfoiled/leveldb

数据库被储存在携带版世界的db/子文件夹。似乎这也是地形文件的存储位置。因为你可以用一个无限世界的db文件夹来替换旧世界的db文件夹,这样就可以把一个旧世界转换为无限世界。

储存在数据库的资料有三种类型:地形数据,实体数据,方块实体数据。

键值形式:9字节长的键值,可能由下述所组成:

  • 为小端序整数的区块X坐标
  • 为小端序整数的区块Z坐标
  • 另外的1个字节表示该数据的类型:
    • 0x30(48 以十进位显示、'0' ASCII)可能为地形数据
    • 0x31(49 以十进位显示、'1' ASCII)为方块实体数据
    • 0x32(50 以十进位显示、'2' ASCII)为实体数据
    • 0x76(118 以十进位显示、'v' ASCII)为1字节的数据

自从0.12.1版本推出了下界,就有了特殊的记录下界数据的秘钥,大小有13比特,好像有:

  • 为小端序整数的区块X坐标
  • 为小端序整数的区块Z坐标
  • 1 as little endian integer (0x01 0x00 0x00 0x00)
  • one more byte indicating the type of the data:
    • 0x30(48 以十进位显示、'0' ASCII)可能为地形数据
    • 0x31(49 以十进位显示、'1' ASCII)为方块实体数据
    • 0x32(50 以十进位显示、'2' ASCII)为实体数据
    • 0x76(118 以十进位显示、'v' ASCII)为1字节的数据

The 0x30 terrain data entry appears to contain block data for an x*z*y = 16*16*128 block chunk. The value associated with the 0x30 terrain data key is always of length 83,200 and seems to consist of the following data:

  • 32,768 bytes of block data which appears to be a x*z*y = 16*16*128 block chunk.
  • 16,384 bytes of regular data (one nibble for each byte of block data above).
  • 16,384 bytes of skylight data (one nibble for each byte of block data above).
  • 16,384 bytes of block light data (one nibble for each byte of block data above).
  • 256 bytes of additional data which appears to be a z*x = 16*16 byte array (one byte for each vertical y column of 128 bytes of block data above) containing dirty column info.
  • 1,024 bytes of additional data which appears to be a 16*16*4 byte array (four bytes for each vertical y column of 128 bytes of block data above) containing grass color info.

The following definitions are provided to clarify the mapping between the location of a block within a LevelDB entry containing a chunk of 32,768 blocks and the corresponding location of the block within the entire world:

  • Let X and Z be the values contained within the LevelDB key.
  • Let C [] be a three dimensional array of the chunk of 32,768 blocks contained within the LevelDB entry. The first two indices i and j range from 0 to 15, and the third index y ranges from 0 to 127.
  • Let W [] be a three dimensional array of the blocks contained within the entire world.
    • For old style worlds, the first two indices x and z both range from 0 to 255. For infinite worlds, the first two indices x and z both range over the values of a four byte integer and may be negative as well as positive.
    • The third index y ranges from 0 to 127 for both old style and infinite worlds.

Assuming the definitions above, the location of a block with a LevelDB entry with key values X and Z maps to the corresponding location of the block within the entire world as follows:

  • C [i, j, y] <-> W [x, z, y] where x = 16*X + i and z = 16*Z + j

The x index specifies the North to South location where a smaller value of x is farther North than a larger value of x. The z index specifies the East to West location where a smaller value of z is farther East than a larger value of z. The y index specifies the vertical location where a smaller value of y is at a lower height than a larger value of y. For an old style world, the block at the bottom of the North-East corner of the world is W [0, 0, 0].

The 0x31 tile entity and 0x32 entity data entries above are NBT encoded and may contain 0, 1, or multiple-concatenated Compound tags at the root level. In the case of 0 Compound tags, LevelDB indicates 0 as the length of the value associated with the key. Multiple-concatenated tags are supported because there can be more than one entity per chunk. Every 0x31 tile entity and 0x32 entity entry has an associated 0x30 terrain entry, but an 0x30 terrain entry will not necessarily have an associated 0x31 tile entity or 0x32 entity entry.

The number of 0x30 terrain entries and 0x76 1-byte data entries is always the same, and there is a one-to-one relationship between these entries where the corresponding entries both have the same x and z values. Three values have been observed for the 1-byte data including the binary values 0, 1, and 2. The value 0 has been observed in old style worlds, and the values 1 and 2 have been observed in infinite worlds.

There's also the special key ~local_player for an entity data entry that holds the local player entity. If entity data exists here, it takes precedence over the player data stored in level.dat. The value associated with the ~local_player key is NBT encoded and only has a single compound tag at the root level.

There's also a special key for remote players which consists of two parts. The first part is the prefix "player_" (without the quotes) and the second part is the client ID which is contained in the remote player's clientid.txt file. For example, player_-12345678 would be the key for a remote client with an client ID of -12345678. The value associated with the “player_” prefixed key is NBT encoded and only has a single compound tag at the root level.

There's also a special “game_flatworldlayers” key of length 20 for flat worlds. The value associated with this key is a set of numbers in ASCII text format. An example of a value associated with the “game_flatworldlayers” key is “[7,3,3,2]” where the value length for this example is 9.

level.dat[编辑 | 编辑源代码]

level.dat 的结构与0.8.1及以下版本的很相似。

结构[编辑 | 编辑源代码]


  • 世界数据

    •  Dimension: 玩家的维度,0是 Overworld.

    •  GameType: 是在生存(0)还是在创造(1)模式。

    •  Generator: 世界类型:旧,无限,或超平坦

    •  LastPlayed: Stores the Unix time stamp (in seconds) when the player saved the game.

    •  LevelName: 指定这个存档的名字.

    • LimitedWorldOrigin. (Only applies to old type worlds)

      •  LimitedWorldOriginX: X coordinate where limited world generation started.

      •  LimitedWorldOriginY: Y coordinate where limited world generation started.

      •  LimitedWorldOriginZ: Z coordinate where limited world generation started.

    •  Platform: Seems to store the platform that the level is created on. Currently observed value is 2.

    •  RandomSeed: 地图种子

    •  SizeOnDisk: 估计的存档大小(字节)

    • 在世界中的生成坐标

      •  SpawnX: 玩家生成位置的X坐标。默认为0。

      •  SpawnY: 玩家生成位置的Y坐标。默认为64。

      •  SpawnZ: 玩家生成位置的Z坐标。默认为0。

    •  StorageVersion:携带版存储工具版本, 目前为4

    •  Time: Stores the current "time of day" in ticks. There are 20 ticks per real-life second, and 14400 ticks per Minecraft day/night cycle, making the full cycle length 12 minutes—8 minutes shorter than the standard 20 minute day/night cycle. 0 is the start of daytime, 7200 is the start of sunset, 8280 is the start of nighttime, 13320 is the start of sunrise, and 14400 is daytime again. The value stored in level.dat is always increasing and can be larger than 14400, but the "time of day" is always modulo 14400 of the "Time" field value.

    •  dayCycleStopTime:增加在8.0。默认是18446744073709552000。

    •  spawnMobs: Disable (0) or enable (1) mob spawning.

LOG[编辑 | 编辑源代码]

The LOG files are located at the /db path of a level, and are part of the leveldb format, used in between compaction of the LDB files. It is similar to a Log file for a program. The format is:

YYYY /MM/DD-Hour/Minute/Second.StepName "Info"

Example:

2014/07/24-22:20:08.400488 4a3638 Recovering log #3

0.8.1及以前[编辑 | 编辑源代码]

level.dat[编辑 | 编辑源代码]

level.dat的格式在0.2.0版时被修改了;它现在是一个基于计算机版本的level.dat格式的NBT格式的文件。 在一个0.2.0 移动版之后的世界里, level.dat 是一个存储了环境数据(比如时间)和玩家的健康值、背包、速度和地图内的位置的未压缩的小端序NBT文件。

这个文件有8字节的文件头。包括一个小端序的4字节表明文件类型的整数,对于level.dat是3(更新前是2)。 在它之后是另一个整数,表明了文件除去文件头之外的大小。[2]

NBT结构[编辑 | 编辑源代码]


  • 世界数据。

    •  GameType: 生存模式时为0,创造模式时为1。

    •  LastPlayed: 存储玩家保存游戏文件时的Unix 时间戳(以秒的形式)。

    •  LevelName: 世界名称。

    •  Platform: 看起来是用来存储世界所创建时的平台的。目前观察到的值是2。

    •  Player: 玩家实体信息。它缺少id标签并且有附加元素:

      •  Armor: 每个列表中的TAG_Compound定义了玩家正穿着的一件盔甲。这是一个长度4的列表。对应着头盔、胸甲、护腿和靴子。

        • 背包物品数据。

          •  id: 物品或方块的ID。

          •  Count: 物品在背包内堆叠的数量。任何物品都能堆叠,包括工具。范围在1-255之间。高于255的值在游戏内不会显示。

          •  Damage: 对于盔甲, 是盔甲的损害值。盔甲满的损害值意味着没有损伤。在损害值到达0时,它会损坏然后消失。

      •  Dimension: 玩家所在的维度。0代表主世界。

      •  Inventory: 列表内的每个TAG_Compound定义了一个玩家正在携带或手持的物品。

        • 背包物品数据。

          •  Slot: 标志着这件物品在哪个背包槽内。

          •  id: 物品或方块的ID。

          •  Count: 物品在背包内堆叠的数量。任何物品都能堆叠,包括工具。范围在1-255之间。高于255的值在游戏内不会显示。

          •  Damage: 对于工具, 是工具的耐久值。工具满的耐久值(比如金质工具的33)意味着没有损伤。在损害值到达0时,它会损坏然后消失。

      •  Score: 玩家分数。

    •  RandomSeed: 为生成地形用的随机种子。

    •  SizeOnDisk: 字节形式的整个世界的大小。

    •  SpawnX: 玩家出生点的X坐标(默认为0)。

    •  SpawnY: 玩家出生点的Y坐标(默认为64)。

    •  SpawnZ: 玩家出生点的Z坐标(默认为0)。

    •  StorageVersion: 当前的携带版NBT的版本。当前为3。

    •  Time: 以刻的形式存储的当天时间。每一真实生活中的秒中有20刻, 每Minecraft日有14400刻,是整个日夜循环只有12分钟的长度(比标准的20分钟日夜循环短8分钟)。0是白天的开始,7200是日落的开始,8280是夜晚的开始, 13320是是日出的开始, 14400 又到了白天. 存储在level.dat内的值总是增加并且可以大于14400,但当天时间总是Time字段除以14400的余数。

chunks.dat[编辑 | 编辑源代码]

这个文件存储16x16(256)个区块的数组,保存了每个默认地图的全部256x256x128(8,388,608)个方块。每个 4096字节(或者说4kb)是一个区域长度,一个默认地图内有5377个区域 。这个文件最高可以储存32x32(1024)个区块或是512x512x128(33,554,432)个方块, 在在游戏生成的默认地图中,地图会处在一个标准的大小。文件内的字节类型绝大多数为32位的小端序, 除了几个区域的数据。

第一个区域是数据位置表,指向哪些区块是可用的和它们在地图和本文件内的位置。数据位置表的每128字节描述了地图中的一行区块,但它经常只有64字节长,因为每行只有16个区块。

在数据位置表中的每个区块是15 XX ZZ 00, 15 (21hex) 描述了本节中有多少个区域,第二个数字是16进制的区块左上角的X坐标,第三个数字是16进制的当前区块所在的行的Z坐标, 最后一个数字保持未使用直到一个导致地图大小变大的更新发生。

要寻找一个区块在表中的偏移值,所有必须做的就是使用这个算法:4096+(x*21*4096)+(z*21*16*4096),第一个区域是位置表,所以我们从4096位置开始。每21*4096字节是一个新区块,所以乘x。Z坐标同理,每16区块为一行,所以乘16。

在前8个区域的方块信息后是四个存储确切方块数据的使用大端序的区域。每字节代表两个方块。

在这4个区域之后是4个区域的天顶光照信息。 每字节是两个方块并要用大端序读取。光照值是F表示黑暗,光照值是0表示光亮。因为游戏动态生成光照所以通过外部程序修改此值是无意义的。

player.dat[编辑 | 编辑源代码]

在0.2.0前的版本,这个文件储存了玩家背包信息(现在位于level.dat)。

entities.dat[编辑 | 编辑源代码]

这个文件在0.2.0 Alpha版加入,使用经修改的小端序NBT格式。它以一种基于Alpha世界格式的格式存储实体信息。 在0.3.2时,这个文件被扩展以存储 方块实体值信息。

这个文件具有12字节的头部,以ASCII字符串"ENT"开始,后跟一个0,再是一个小端序的整数1,后跟另一个小端序整数表明字节形式的文件长度(不包括头部)。[2]

NBT结构[编辑 | 编辑源代码]


  • 根复合标签。

    •  Entities: 每个列表中的TAG_Compound定义了世界内的一个实体。

    •  TileEntities: 每个列表中的TAG_Compound定义了一个方块实体值,例如世界中的一个熔炉

实体格式[编辑 | 编辑源代码]

每个实体是一个包含在区块文件中的实体列表中的TAG_Compound。唯一的例外是玩家实体(储存在level.dat中)。

所有实体共享这个基类:


  • 实体数据

    •  id: 实体ID。13 代表着羊,32代表着僵尸,64代表着掉落物。

    •  Pos: 3个TAG_Floats描述实体当前的 X,Y,Z坐标。

    •  Motion: 3个TAG_Floats 描述实体当前的dX,dY,dZ 速度。 (注意: 0,0,0 代表无动作)

    •  Rotation: 2个TAG_Floats描述当前以度为单位的倾斜度。

      • :实体Y轴的顺时针倾斜度。朝西为0。因为它累计生物在游戏中的每次倾斜,所以可以是一个很大的值。

      • : 实体Y轴的从水平开始的倾斜度。水平为0。为负值时看起来向下。不要超过正负90度。

    •  FallDistance: 实体已下落的距离。越大时当实体落地时会造成更大伤害。

    •  Fire: 距离火焰熄灭还剩多少刻。负值反映实体在火焰中能保持多久不燃烧。

    •  Air: 实体有多少空气(刻的形式).在空气中为300。在水下时减少。

    •  OnGround: 当实体接地时为1。

生物[编辑 | 编辑源代码]

  • 生物的附加字段:

    •  AttackTime: 实体的"无敌盾牌"在受到打击后保持的刻形式的时间长度。

    •  DeathTime: 生物已死亡的刻数。控制死亡动画。

    •  Health: 生物拥有的健康值。玩家和敌对生物最高有20点,牲畜最高有10点。

    •  HurtTime: 未知。
  • 动物的附加字段(比如羊):

    •  Age: 动物年龄。可能被后续版本中的幼年动物使用。

Sheep 羊有两个附加字段:


    •  Sheared: 1或0 (true/false) - 已剪毛时为1。

    •  Color: 0到15 - 现有一个证据表明此值不影响羊的颜色,但影响羊的羊毛掉落的颜色。[3]
  • 物品附加字段:

    •  Health: 从5开始,目前仅当物品受到火焰伤害时降低。降至0时物品被摧毁。

    •  Age: 物品掉落在地上的时间.在2400刻或者说2分钟后,物品会被摧毁。

    •  Item: 物品数据

      •  id: 物品或方块ID

      •  Damage: 物品的损害值。0代表着无损害。当损害值超过物品耐久值时,它会损坏然后消失。只有盔甲和工具会正常累加损害值。

      •  Count: 掉落物实体包含的物品数量。任何物品都能堆叠,包括工具、盔甲和交通工具,范围在0-255之间。

参考[编辑 | 编辑源代码]