<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.sasgaming.net/index.php?action=history&amp;feed=atom&amp;title=Minecraft%3AJava_Edition_protocol%2FChunk_format</id>
	<title>Minecraft:Java Edition protocol/Chunk format - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.sasgaming.net/index.php?action=history&amp;feed=atom&amp;title=Minecraft%3AJava_Edition_protocol%2FChunk_format"/>
	<link rel="alternate" type="text/html" href="https://wiki.sasgaming.net/index.php?title=Minecraft:Java_Edition_protocol/Chunk_format&amp;action=history"/>
	<updated>2026-06-10T23:05:52Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki.sasgaming.net/index.php?title=Minecraft:Java_Edition_protocol/Chunk_format&amp;diff=141121&amp;oldid=prev</id>
		<title>SyncBot: Sync: new page from Minecraft</title>
		<link rel="alternate" type="text/html" href="https://wiki.sasgaming.net/index.php?title=Minecraft:Java_Edition_protocol/Chunk_format&amp;diff=141121&amp;oldid=prev"/>
		<updated>2026-06-10T11:15:02Z</updated>

		<summary type="html">&lt;p&gt;Sync: new page from Minecraft&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This article describes in additional detail the format of the [[Minecraft:Java Edition protocol/Packets#Chunk_Data_and_Update_Light|Chunk Data]] packet.&lt;br /&gt;
&lt;br /&gt;
== Concepts ==&lt;br /&gt;
&lt;br /&gt;
=== Chunks columns and Chunk sections ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ve probably heard the term &amp;quot;chunk&amp;quot; before. Minecraft uses chunks to store and transfer world data.  However, there are actually 2 different concepts that are both called &amp;quot;chunks&amp;quot; in different contexts: chunk columns and chunk sections.&lt;br /&gt;
&lt;br /&gt;
{{Anchor|Chunk column}}A &amp;#039;&amp;#039;&amp;#039;chunk column&amp;#039;&amp;#039;&amp;#039; is a collection of blocks with a horizontal size of 16&amp;amp;times;16, spanning the entire buildable area on the vertical axis.  This is what most players think of when they hear the term &amp;quot;chunk&amp;quot;.  However, these are not the smallest unit data is stored in the game; chunk columns are vertically divided into chunk sections, each 16 blocks tall.&lt;br /&gt;
&lt;br /&gt;
Chunk columns store block entities, entities, tick data, and an array of sections.&lt;br /&gt;
&lt;br /&gt;
{{Anchor|Chunk section}}A &amp;#039;&amp;#039;&amp;#039;chunk section&amp;#039;&amp;#039;&amp;#039; is a 16&amp;amp;times;16&amp;amp;times;16 collection of blocks (chunk sections are cubic).  This is the actual area that blocks are stored in, and is often the concept Mojang refers to via &amp;quot;chunk&amp;quot;.  Breaking columns into sections wouldn&amp;#039;t be useful, except that you don&amp;#039;t need to send all chunk sections in a column: If a section is empty, then it doesn&amp;#039;t need to be sent (more on this later).&lt;br /&gt;
&lt;br /&gt;
Chunk sections store blocks, biomes and light data (both block light and sky light).  Additionally, they can be associated with at most two [[#Local palettes|local palettes]]&amp;amp;mdash;one for blocks, one for biomes.  A chunk section can contain at maximum 4096 (16&amp;amp;times;16&amp;amp;times;16, or 2&amp;lt;sup&amp;gt;12&amp;lt;/sup&amp;gt;) unique block state IDs, and 64 (4&amp;amp;times;4&amp;amp;times;4) unique biome IDs (but, it is highly unlikely that such a section will occur in normal circumstances).&lt;br /&gt;
&lt;br /&gt;
Chunk columns and chunk sections are both displayed when chunk border rendering is enabled (&amp;lt;kbd&amp;gt;F3&amp;lt;/kbd&amp;gt;+&amp;lt;kbd&amp;gt;G&amp;lt;/kbd&amp;gt;).  Chunk columns borders are indicated via the red vertical lines, while chunk sections borders are indicated by the blue lines.&lt;br /&gt;
&lt;br /&gt;
=== Global palettes ===&lt;br /&gt;
&lt;br /&gt;
The global palettes map block states and biomes to protocol-wide numeric identifiers.&lt;br /&gt;
&lt;br /&gt;
==== Global block state palette ====&lt;br /&gt;
&lt;br /&gt;
The global block state palette is generated based on the &amp;lt;code&amp;gt;minecraft:block&amp;lt;/code&amp;gt; [[Minecraft:Java Edition protocol/Registries|registry]], which in turn is hardcoded into Minecraft, and can only be changed via modding. Such changes break protocol compatibility, and as such, modding frameworks typically include protocol extensions to negotiate which IDs the client and server have in common.&lt;br /&gt;
&lt;br /&gt;
One block state ID is allocated for each unique block state of a block; if a block has multiple properties then the number of allocated states is the product of the number of values for each property. The block state IDs belonging to a given block are always consecutive. Other than that, the ordering of block states is hardcoded, and somewhat arbitrary.&lt;br /&gt;
&lt;br /&gt;
The [[Minecraft:Minecraft Wiki:Projects/wiki.vg merge/Data Generators|Data Generators]] system can be used to generate a list of all block state IDs.&lt;br /&gt;
&lt;br /&gt;
==== Biome registry ====&lt;br /&gt;
&lt;br /&gt;
The global palette for biomes is the &amp;lt;code&amp;gt;minecraft:worldgen/biome&amp;lt;/code&amp;gt; [[Minecraft:Java Edition protocol/Registries#Synchronized registries|synchronized registry]], which is defined at runtime in a [[Minecraft:Java Edition protocol/Packets#Registry Data 2|Registry Data]] packet sent by the server during the Configuration phase.&lt;br /&gt;
&lt;br /&gt;
The vanilla server pulls these biome definitions [[Minecraft:Biome definition|from data packs]].&lt;br /&gt;
&lt;br /&gt;
=== Local palettes ===&lt;br /&gt;
&lt;br /&gt;
[[File:Indexed_palette.png|thumb|Illustration of an indexed palette ([[Commons:File:Indexed_palette.png|Source]])]]&lt;br /&gt;
&lt;br /&gt;
A local palette maps a smaller set of IDs within a [[#Chunk section|chunk section]] to global palette IDs. Other than skipping empty sections, correct use of palettes is the biggest place where data can be saved. For example, encoding any of the IDs in the global block state palette as of vanilla 1.20.2 requires 15 bits. Given that most sections contain only a few different blocks, using 15 bits per block to represent a chunk section that is only stone, gravel, and air would be extremely wasteful.  Instead, a list of global palette IDs is sent to define the local palette (for instance, &amp;lt;code&amp;gt;40 57 0&amp;lt;/code&amp;gt;), and indices into that list are sent as the block state or biome values within the chunk (so &amp;lt;code&amp;gt;40&amp;lt;/code&amp;gt; would be sent as &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;57&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt;).&amp;lt;ref group=&amp;quot;concept note&amp;quot;&amp;gt;There is no requirement for the global palette IDs listed in a local palette to be [[Wikipedia:Monotonic|monotonic]]; the order within the list is entirely arbitrary and often has to do with how the palette is built (if it finds a stone block before an air block, stone can come first).  (However, although the order of the palette entries can be arbitrary, it can theoretically be optimized to ensure the maximum possible DEFLATE compression.  This optimization offers little to no gain, so generally do not attempt it.)  However, there shouldn&amp;#039;t be any gaps in the palette, as gaps would increase the size of the palette when it is sent.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The number of bits used to encode local palette indices varies based on the number of indices, and the global palette in question. If a threshold on the number of unique IDs in the section is exceeded, a local palette is not used, and global palette IDs are used directly instead.&lt;br /&gt;
&lt;br /&gt;
The concept of palettes is more commonly used with colors in an image; Wikipedia&amp;#039;s articles on [[Wikipedia:Color look-up table|color look-up tables]], [[Wikipedia:Indexed color|indexed colors]], and [[Wikipedia:Palette (computing)|palettes in general]] may be helpful for fully grokking it.&lt;br /&gt;
&lt;br /&gt;
{{warning|Note that the notchian client (and server) store their chunk data within the compacted, paletted format.  Sending non-compacted data not only wastes bandwidth, but also leads to increased memory use clientside; while this is OK for an initial implementation it is strongly encouraged that one compacts the block data as soon as possible.}}&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references group=&amp;quot;concept note&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Packet structure ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! Packet ID&lt;br /&gt;
 ! State&lt;br /&gt;
 ! Bound To&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 |rowspan=&amp;quot;7&amp;quot;| 0x27&lt;br /&gt;
 |rowspan=&amp;quot;7&amp;quot;| Play&lt;br /&gt;
 |rowspan=&amp;quot;7&amp;quot;| Client&lt;br /&gt;
 | Chunk X&lt;br /&gt;
 | {{Type|Int}}&lt;br /&gt;
 | Chunk coordinate (block coordinate divided by 16, rounded down).&lt;br /&gt;
 |-&lt;br /&gt;
 | Chunk Z&lt;br /&gt;
 | {{Type|Int}}&lt;br /&gt;
 | Chunk coordinate (block coordinate divided by 16, rounded down).&lt;br /&gt;
 |-&lt;br /&gt;
 | Heightmaps&lt;br /&gt;
 | {{Type|Prefixed Array}} of [[#Heightmap structure|Heightmap]]&lt;br /&gt;
 | See [[#Heightmap structure]] below.&lt;br /&gt;
 |- &lt;br /&gt;
 | Size&lt;br /&gt;
 | {{Type|VarInt}}&lt;br /&gt;
 | Size of Data in bytes; in some cases this is larger than it needs to be (e.g. [https://bugs.mojang.com/browse/MC-131684 MC-131684], [https://bugs.mojang.com/browse/MC-247438 MC-247438]) in which case extra bytes should be skipped before reading fields after Data.&lt;br /&gt;
 |-&lt;br /&gt;
 | Data&lt;br /&gt;
 | {{Type|Byte Array}}&lt;br /&gt;
 | See [[#Data structure]] below.&lt;br /&gt;
 |-&lt;br /&gt;
 | Additional Data&lt;br /&gt;
 | Various&lt;br /&gt;
 | See [[Minecraft:Java Edition protocol/Packets#Chunk Data and Update Light|Protocol#Chunk Data and Update Light]].&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Heightmap structure ===&lt;br /&gt;
&lt;br /&gt;
Minecraft uses heightmaps to optimize various operations on both the server and the client. All heightmaps encode the position of the highest &amp;quot;occupied&amp;quot; block in each column of blocks within a chunk column. The differences have to do with which blocks are considered to be &amp;quot;occupied&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Rather than calculating them from the chunk data, the client receives the initial heightmaps it needs from the server. This trades an increase in network usage for a decrease in client-side processing. Once a chunk is loaded, the client updates its heightmaps based on block changes independently from the server.&lt;br /&gt;
&lt;br /&gt;
No heightmaps are strictly required for the client to accept a chunk. If a heightmap is missing from a Chunk Data packet, the client will initialize it with all heights set to their minimum values. However, block changes will still cause the corresponding height values to be updated as normal.&lt;br /&gt;
&lt;br /&gt;
As of 1.21.5, the Heightmap structure is as follows.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Heightmap Structure&lt;br /&gt;
|-&lt;br /&gt;
! Field Name !! Field Type !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Type || {{Type|VarInt}} {{Type|Enum}} || See the table below.&lt;br /&gt;
|-&lt;br /&gt;
| Data || {{Type|Prefixed Array}} of {{Type|Long}} || Packed data array. Described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The height values of a heightmap are packed into the long array in the same manner described in [[#Data Array format]], and ordered such that the fastest-increasing coordinate is x. (However, there are only 256 entries&amp;amp;mdash;one for each block column.) The Bits Per Entry value used is calculated as ceil(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;(&amp;lt;var&amp;gt;world_height&amp;lt;/var&amp;gt; + 1)). This is because the number of possible height values is one more than the world height&amp;amp;mdash;ranging from 0 (completely blank column; not even bedrock) to world height (highest position is occupied). Note that this means, for example, that a world with height 256 will use a Bits Per Entry of 9. Since the minimum world height might be negative, it must be added as an offset to get the actual highest occupied Y coordinate.&lt;br /&gt;
&lt;br /&gt;
The following heightmaps are currently used by the client:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! Name&lt;br /&gt;
 ! ID&lt;br /&gt;
 ! Considers Occupied&lt;br /&gt;
 ! Purposes&lt;br /&gt;
 |-&lt;br /&gt;
 | WORLD_SURFACE&lt;br /&gt;
 | 1&lt;br /&gt;
 | All blocks other than air, cave air and void air.&lt;br /&gt;
 | To determine if a beacon beam is obstructed.&lt;br /&gt;
 |-&lt;br /&gt;
 | MOTION_BLOCKING&lt;br /&gt;
 | 4&lt;br /&gt;
 | &amp;quot;Solid&amp;quot; blocks, except bamboo saplings and cactuses; fluids.&lt;br /&gt;
 | To determine where to display rain and snow.&lt;br /&gt;
 |-&lt;br /&gt;
 | MOTION_BLOCKING_NO_LEAVES&lt;br /&gt;
 | 5&lt;br /&gt;
 | Same as MOTION_BLOCKING, excluding leaf blocks.&lt;br /&gt;
 |&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
This list is exhaustive as of 1.21.8. The listed purposes appear to be exhaustive as of 1.20.2.&lt;br /&gt;
&lt;br /&gt;
=== Data structure ===&lt;br /&gt;
&lt;br /&gt;
The data section of the packet contains most of the useful data for the chunk.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 | Data&lt;br /&gt;
 | {{Type|Array}} of [[#Chunk Section structure|Chunk Section]]&lt;br /&gt;
 | This array is NOT length-prefixed. The number of elements in the array is calculated based on the world&amp;#039;s height. Sections are sent bottom-to-top. Starting with 1.18, the world height changes based on the dimension. The height of each dimension is assigned by the server in its corresponding entry in the &amp;lt;code&amp;gt;minecraft:dimension_type&amp;lt;/code&amp;gt; [[Minecraft:Java Edition protocol/Registries#Synchronized registries|synchronized registry]]. For example, the vanilla overworld is 384 blocks tall, meaning 24 chunk sections will be included in this array. &lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
==== Chunk Section structure ====&lt;br /&gt;
&lt;br /&gt;
{{Update|section=1|How do biomes work now?  The biome change happened at the same time as the seed change, but it&amp;#039;s not clear how/if biomes could be computed given that it&amp;#039;s not the actual seed...  ([https://www.reddit.com/r/Mojira/comments/e5at6i/a_discussion_for_the_changes_to_how_biomes_are/ /r/mojira discussion] which notes that it seems to be some kind of interpolation)}}&lt;br /&gt;
{{warning|The Fluid count only appear in 26.1 +}}&lt;br /&gt;
A Chunk Section is defined in terms of other [[Minecraft:Java Edition protocol/Data types|data types]]. A Chunk Section consists of the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 | Block count&lt;br /&gt;
 | {{Type|Short}}&lt;br /&gt;
 | Number of non-air blocks present in the chunk section. &amp;quot;Non-air&amp;quot; is defined as any fluid and block other than air, cave air, and void air. The client will keep count of the blocks as they are broken and placed, and, if the block count reaches 0, the whole chunk section is not rendered, even if it still has blocks.&lt;br /&gt;
 |-&lt;br /&gt;
 | Fluid count&lt;br /&gt;
 | {{Type|Short}}&lt;br /&gt;
 | Number of fluids &amp;lt;ref&amp;gt;[[Minecraft:Fluid|fluids]] are (flowing) lava and (flowing) water&amp;lt;/ref&amp;gt; in this chunk section.&lt;br /&gt;
 |-&lt;br /&gt;
 | Block states&lt;br /&gt;
 | [[#Paletted Container structure|Paletted Container]]&lt;br /&gt;
 | Consists of 4096 entries, representing all the blocks in the chunk section.&lt;br /&gt;
 |-&lt;br /&gt;
 | Biomes&lt;br /&gt;
 | [[#Paletted Container structure|Paletted Container]]&lt;br /&gt;
 | Consists of 64 entries, representing 4&amp;amp;times;4&amp;amp;times;4 biome regions in the chunk section.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
== Paletted Container structure ==&lt;br /&gt;
&lt;br /&gt;
A Paletted Container is a palette-based storage of entries. Paletted Containers have an associated global palette (either block states or biomes as of now), where values are mapped from. A Paletted Container consists of the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 | Bits Per Entry&lt;br /&gt;
 | {{Type|Unsigned Byte}}&lt;br /&gt;
 | Determines how many bits are used to encode entries. Note that not all numbers are valid here.&lt;br /&gt;
 |-&lt;br /&gt;
 | Palette&lt;br /&gt;
 | Varies&lt;br /&gt;
 | See [[#Palette formats]] below.&lt;br /&gt;
 |-&lt;br /&gt;
 | Data Array&lt;br /&gt;
 | {{Type|Array}} of {{Type|Long}}&lt;br /&gt;
 | See [[#Data Array format]] below.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Palette formats ===&lt;br /&gt;
&lt;br /&gt;
The Bits Per Entry value determines what format is used for the Palette field, which in turn determines how values in the Data Array map to the global palette.&lt;br /&gt;
&lt;br /&gt;
{{warning|Values not listed in the following table are rounded upwards to the next one specified, or downwards if larger than the value for Direct. Therefore such values will lead to unexpected results, and should not be used.}}&lt;br /&gt;
&lt;br /&gt;
There are currently three possible palette formats:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 ! &amp;lt;abbr title=&amp;quot;Bits Per Entry&amp;quot;&amp;gt;BPE&amp;lt;/abbr&amp;gt; (blocks)&lt;br /&gt;
 ! &amp;lt;abbr title=&amp;quot;Bits Per Entry&amp;quot;&amp;gt;BPE&amp;lt;/abbr&amp;gt; (biomes)&lt;br /&gt;
 ! Palette Format&lt;br /&gt;
 |-&lt;br /&gt;
 | 0&lt;br /&gt;
 | 0&lt;br /&gt;
 | [[#Single valued|Single valued]]&lt;br /&gt;
 |-&lt;br /&gt;
 | 4-8&lt;br /&gt;
 | 1-3&lt;br /&gt;
 | [[#Indirect|Indirect]]&lt;br /&gt;
 |-&lt;br /&gt;
 | 15**&lt;br /&gt;
 | 7*&lt;br /&gt;
 | [[#Direct|Direct]]&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;The Notchian client calculates the Bits Per Entry values for the Direct palette format at runtime based on the sizes of the global block state and biome palettes. As such, the value used for biomes is entirely dependent on the contents of the biome registry sent in the [[Minecraft:Java Edition protocol/Packets#Registry Data 2|Registry Data]] packet; the value shown is only valid for vanilla servers with no custom data packs. If the BPE requirement for Direct is less than or equal to the maximum for Indirect, Direct will never be used given BPE values within the valid range.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;**&amp;lt;/nowiki&amp;gt;Similarly, if a sufficiently large number of blocks is added with mods, the value will be increased to compensate for the increased ID count. This increase can go up to 31 bits per entry (since registry IDs are signed integers). In case of Minecraft Forge, you can get the number of blocks with the &amp;quot;Number of ids&amp;quot; field found in the [[Minecraft:Minecraft Wiki:Projects/wiki.vg merge/Minecraft Forge Handshake#RegistryData|RegistryData packet in the Forge Handshake]].&lt;br /&gt;
&lt;br /&gt;
==== Single valued ====&lt;br /&gt;
&lt;br /&gt;
When this palette format is used, the Data Array sent/received is empty, since entries can be inferred from the palette&amp;#039;s single value.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |- class=&amp;quot;tc-yes&amp;quot;&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 | Value&lt;br /&gt;
 | {{Type|VarInt}}&lt;br /&gt;
 | ID of the entry in the global palette.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
==== Indirect ====&lt;br /&gt;
&lt;br /&gt;
This is an actual palette which lists the entries used. Values in the Data Array are indices into the local palette, which in turn gives a proper global palette ID.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 | Palette Length&lt;br /&gt;
 | {{Type|VarInt}}&lt;br /&gt;
 | Number of elements in the following array.&lt;br /&gt;
 |-&lt;br /&gt;
 | Palette&lt;br /&gt;
 | {{Type|Array}} of {{Type|VarInt}}&lt;br /&gt;
 | Mapping of IDs in the global palette to indices of this array.&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
==== Direct ====&lt;br /&gt;
&lt;br /&gt;
Global palette IDs are stored directly as entries in the Data Array.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 ! Field Name&lt;br /&gt;
 ! Field Type&lt;br /&gt;
 ! Notes&lt;br /&gt;
 |-&lt;br /&gt;
 |colspan=&amp;quot;3&amp;quot;| &amp;#039;&amp;#039;no fields&amp;#039;&amp;#039;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here is an example showing a Chunk Section using a single-valued palette for block states, and an indirect palette with 2 indices for biomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid red&amp;quot;&amp;gt;00 00&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid blue&amp;quot;&amp;gt;00 00&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid orange&amp;quot;&amp;gt;00&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid lime&amp;quot;&amp;gt;00&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid orange&amp;quot;&amp;gt;01&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid yellow&amp;quot;&amp;gt;02&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid lime&amp;quot;&amp;gt;27 03&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: 2px solid aqua&amp;quot;&amp;gt;CC FF CC FF CC FF CC FF&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The first bytes &amp;lt;span style=&amp;quot;border: 2px solid red&amp;quot;&amp;gt;00 00&amp;lt;/span&amp;gt; are the number of non-air blocks in the chunk.&lt;br /&gt;
Right after, &amp;lt;span style=&amp;quot;border: 2px solid blue&amp;quot;&amp;gt;00 00&amp;lt;/span&amp;gt; are the number of fluid in the chunk.&lt;br /&gt;
They are followed by the Bits Per Entry &amp;lt;span style=&amp;quot;border: 2px solid orange&amp;quot;&amp;gt;00&amp;lt;/span&amp;gt;, which is zero so we know the palette will have one element (not prefixed with length). This single element is the block state ID of air, &amp;lt;span style=&amp;quot;border: 2px solid lime&amp;quot;&amp;gt;00&amp;lt;/span&amp;gt;.&lt;br /&gt;
  &lt;br /&gt;
The second part of the packet is for biomes. The first byte is their Bits Per Entry &amp;lt;span style=&amp;quot;border: 2px solid orange&amp;quot;&amp;gt;01&amp;lt;/span&amp;gt;, followed by the length of the palette &amp;lt;span style=&amp;quot;border: 2px solid yellow&amp;quot;&amp;gt;02&amp;lt;/span&amp;gt; and the two elements &amp;lt;span style=&amp;quot;border: 2px solid lime&amp;quot;&amp;gt;27 03&amp;lt;/span&amp;gt;. The indexed data of this biome has 1 long element, which are 8 bytes each, giving the long &amp;lt;span style=&amp;quot;border: 2px solid aqua&amp;quot;&amp;gt;CC FF CC FF CC FF CC FF&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Data Array format ===&lt;br /&gt;
&lt;br /&gt;
As of 1.21.5, the length of the data array is no longer sent with the packet, but is instead calculated from the bits per entry and the number of entries.&lt;br /&gt;
&lt;br /&gt;
The Data Array stores entries as Bits Per Entry&amp;amp;ndash;bit integers, corresponding to either local or global palette indices depending on the palette format in use. If Bits Per Entry is 0, it is empty.&lt;br /&gt;
&lt;br /&gt;
Entries are stored in order of increasing x coordinate, within rows at increasing z coordinates, within layers at increasing y coordinates. In other words, the x coordinate increases the fastest, and the y coordinate the slowest.&lt;br /&gt;
&lt;br /&gt;
A single long of the array holds several entries. The entries are tightly packed within the long, with the first entry on the least significant bits. An entry cannot span across multiple longs; instead, padding is inserted as required, starting from the most significant bits.&lt;br /&gt;
&lt;br /&gt;
For example, assuming a bits per block value of 15, and that bit 0 is the least significant bit, the data is stored such that bits 0 through 14 are the first entry, 15 through 29 are the second, and so on. The fourth entry ends on bit 59, and since only 4 bits are left, they become padding, and the fifth entry starts on the next long.&lt;br /&gt;
&lt;br /&gt;
Note that since longs are sent in big endian order, the least significant bit of the first entry in a long will be on the &amp;#039;&amp;#039;last&amp;#039;&amp;#039; byte of the long on the wire.&lt;br /&gt;
&lt;br /&gt;
{{warning|This format was changed in Minecraft 1.16. In prior versions, entries could cross long boundaries, and there was no padding.}}&lt;br /&gt;
&lt;br /&gt;
==== Visual example ====&lt;br /&gt;
&lt;br /&gt;
5 bits per block, containing the following references to entries in a palette (not shown):&lt;br /&gt;
&amp;lt;code&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(  0, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;1&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 30, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;2&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 60, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;2&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 90, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;3&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(120, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;4&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(150, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;4&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(180, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;5&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(210, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;6&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(240, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;6&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(270, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;4&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(300, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;8&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(330, 90%, 60%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;0&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(  0, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;7&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 30, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;4&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 60, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;3&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 90, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;13&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(120, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;15&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(150, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;16&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(180, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;9&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(210, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;14&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(240, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;10&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(270, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;12&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(300, 90%, 30%); margin-left: -2px; padding: 0 1px&amp;quot;&amp;gt;0&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(330, 90%, 30%); margin:    0 -2px; padding: 0 1px&amp;quot;&amp;gt;2&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;0020863148418841&amp;lt;/code&amp;gt;&amp;lt;code&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: dashed 2px black;             margin-left: -2px&amp;quot;&amp;gt;0000&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(330, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00000&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(300, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;01000&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(270, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00100&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(240, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00110&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(210, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00110&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(180, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00101&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(150, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00100&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(120, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00100&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 90, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00011&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 60, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00010&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 30, 90%, 60%); margin-left: -2px&amp;quot;&amp;gt;00010&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(  0, 90%, 60%); margin:    0 -2px&amp;quot;&amp;gt;00001&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;01018A7260F68C87&amp;lt;/code&amp;gt;&amp;lt;code&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: dashed 2px black;             margin-left: -2px&amp;quot;&amp;gt;0000&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(330, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;00010&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(300, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;00000&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(270, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;01100&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(240, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;01010&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(210, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;01110&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(180, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;01001&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(150, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;10000&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(120, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;01111&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 90, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;01101&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 60, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;00011&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl( 30, 90%, 30%); margin-left: -2px&amp;quot;&amp;gt;00100&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;span style=&amp;quot;border: solid 2px hsl(  0, 90%, 30%); margin:    0 -2px&amp;quot;&amp;gt;00111&amp;lt;/span&lt;br /&gt;
&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Hints for implementers ====&lt;br /&gt;
&lt;br /&gt;
The number of entries per long may be calculated as floor(64 / &amp;lt;var&amp;gt;bits_per_entry&amp;lt;/var&amp;gt;). The number of longs in the array may then be calculated as ceil(&amp;lt;var&amp;gt;number_of_entries&amp;lt;/var&amp;gt; / &amp;lt;var&amp;gt;entries_per_long&amp;lt;/var&amp;gt;). It may seem like this calculation could be simplified as &amp;lt;var&amp;gt;number_of_entries&amp;lt;/var&amp;gt; times &amp;lt;var&amp;gt;bits_per_entry&amp;lt;/var&amp;gt; divided by 64, but that formula is incorrect, since the intermediate rounding is significant and accounts for the padding at the end of each long.&lt;br /&gt;
&lt;br /&gt;
In languages that lack a ceiling division operator, one can do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// assuming integer division rounds towards 0, which is usually the case.&lt;br /&gt;
entries_per_long = 64 / bits_per_entry&lt;br /&gt;
number_of_longs = number_of_entries + (entries_per_long - 1) / entries_per_long&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The index of the long an entry is located in may be calculated as floor(&amp;lt;var&amp;gt;entry_index&amp;lt;/var&amp;gt; / &amp;lt;var&amp;gt;entries_per_long&amp;lt;/var&amp;gt;), and the 0-based index of the least significant bit of the entry within the long as (&amp;lt;var&amp;gt;entry_index&amp;lt;/var&amp;gt; % &amp;lt;var&amp;gt;entries_per_long&amp;lt;/var&amp;gt; &amp;amp;times; &amp;lt;var&amp;gt;bits_per_entry&amp;lt;/var&amp;gt;) (where % is the remainder operator).&lt;br /&gt;
&lt;br /&gt;
To read an entry in a language with C-like bitwise operators, one can do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// in some languages it is necessary to cast the 1 to a 64-bit type first, or else&lt;br /&gt;
// the shift will be performed in 32 bits. a C-style cast is shown as an example.&lt;br /&gt;
entry_mask = ((uint64_t)1 &amp;lt;&amp;lt; bits_per_entry) - 1&lt;br /&gt;
long_index = entry_index / entries_per_long&lt;br /&gt;
bit_index = entry_index % entries_per_long * bits_per_entry&lt;br /&gt;
value = (data_array[long_index] &amp;gt;&amp;gt; bit_index) &amp;amp; entry_mask&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And to write an entry:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
data_array[long_index] &amp;amp;= ~(entry_mask &amp;lt;&amp;lt; bit_index)&lt;br /&gt;
// if value has a smaller integer type, it may again be necessary to cast it to 64 bits.&lt;br /&gt;
data_array[long_index] |= (uint64_t)value &amp;lt;&amp;lt; bit_index&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that there are more efficient ways to convert all entries in a section to/from this format, as well as more efficient ways of doing the division and remainder computations for individual accesses with specific &amp;lt;var&amp;gt;bit_per_entry&amp;lt;/var&amp;gt; values. This code merely represents the simplest possible implementation.&lt;br /&gt;
&lt;br /&gt;
== Tips and notes ==&lt;br /&gt;
&lt;br /&gt;
There are several things that can make it easier to implement this format.&lt;br /&gt;
&lt;br /&gt;
* Servers do &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; need to implement the local palette initially (instead always using 15 bits per block), although it is an important optimization later on.&lt;br /&gt;
* The Notchian server implementation does not send values that are out of bounds for the palette.  If such a value is received, the format is being parsed incorrectly.  In particular, if you&amp;#039;re reading a number with all bits set (15, 31, etc), you might be reading skylight data (or you may have a sign error and you&amp;#039;re reading negative numbers).&lt;br /&gt;
* The Notchian client generally does not render chunks that lack neighbors.  (As of 1.20.2 such chunks appear to sporadically become visible anyway, and do so consistently when interacted with.)  This means that if you only send a fixed set of chunks with no empty chunks around them, then some of them will not be visible, although you can still interact with them.  This is intended behavior, so that lighting and connected blocks can be handled correctly.&lt;br /&gt;
&lt;br /&gt;
== Full implementations ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/GlowstoneMC/Glowstone/blob/dev/src/main/java/net/glowstone/chunk/ChunkSection.java Java, 1.12.2, writing only, with palette]&lt;br /&gt;
* [https://github.com/feather-rs/feather/blob/main/feather/base/src/chunk.rs Rust, 1.16.5, with palette]&lt;br /&gt;
* [https://github.com/Steveice10/MCProtocolLib/blob/4ed72deb75f2acb0a81d641717b7b8074730f701/src/main/java/org/spacehq/mc/protocol/data/game/chunk/BlockStorage.java#L42 Java, 1.9, both sides]&lt;br /&gt;
* [https://github.com/barneygale/quarry Python, 1.7 through 1.13]. Read/write, paletted/unpaletted, [https://github.com/barneygale/quarry/blob/master/quarry/types/buffer/v1_7.py#L403 packets]/[https://github.com/barneygale/quarry/blob/master/quarry/types/chunk.py arrays]&lt;br /&gt;
* [https://github.com/SpockBotMC/SpockBot/blob/0535c31/spockbot/plugins/tools/smpmap.py#L144-L183 Python, 1.9, reading only]&lt;br /&gt;
* [https://github.com/Protryon/Osmium/blob/fdd61b9/MinecraftClone/src/ingame.c#L512-L632 C, 1.9, reading only]&lt;br /&gt;
* [https://github.com/Protryon/Basin/blob/master/basin/src/packet.c#L1124 C, 1.11.2, writing only]&lt;br /&gt;
* [https://github.com/cuberite/cuberite/blob/master/src/Protocol/ChunkDataSerializer.cpp#L190 C++, 1.12.2, writing only]&lt;br /&gt;
* [https://github.com/PrismarineJS/prismarine-chunk Node.js, 1.8-&amp;gt;1.18]&lt;br /&gt;
&lt;br /&gt;
== Sample data ==&lt;br /&gt;
&lt;br /&gt;
* [https://gist.github.com/Pokechu22/0b89f928b381dede0387fe5f88faf8c0 some sample data] from 1.13.2, with both complete packets and just the data structures&lt;br /&gt;
* [https://github.com/PrismarineJS/prismarine-chunk/tree/master/test prismarine test data] chunks from 1.8 to 1.20 used as testing data, generated using automated [https://github.com/PrismarineJS/minecraft-chunk-dumper chunk-dumper]&lt;br /&gt;
&lt;br /&gt;
=== Old format ===&lt;br /&gt;
&lt;br /&gt;
The following implement the [https://web.archive.org/https://wiki.vg/index.php?title=SMP_Map_Format&amp;amp;oldid=7164 previous] (before 1.9) format:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/GlowstoneMC/Glowstone/blob/d3ed79ea7d284df1d2cd1945bf53d5652962a34f/src/main/java/net/glowstone/GlowChunk.java#L640 Java, 1.8]&lt;br /&gt;
* [https://github.com/barneygale/smpmap Python, 1.4]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Protocol Details]]&lt;br /&gt;
[[Category:Java Edition protocol]]&lt;br /&gt;
{{license wiki.vg}}&lt;/div&gt;</summary>
		<author><name>SyncBot</name></author>
	</entry>
</feed>