···
+
# Packets <img src=".assets/cc-by-sa.png" alt="CC-BY-SA" width="88" height="31">
+
_This document is licensed under a [Creative Commons Attribution-ShareAlike 4.0
+
license](https://creativecommons.org/licenses/by-sa/4.0/). Derivative works must
+
be licensed using the same or a compatible license._
+
All packets begin with a single "Packet ID" byte. Listed packet size **does not
+
include** this byte. Packets are either Clientbound, Serverbound, or both.
+
Packets that travel both Clientbound and Serverbound may reuse fields for
+
There is no "length" field; for variable length packets, you must parse to the
+
end to determine the length.
+
| | Size (bytes) | Range | Notes |
+
| ----- | ------------ | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
+
| i8 | 1 | -128 to 127 | |
+
| u8 | 1 | 0 to 255 | |
+
| i16 | 2 | -32768 to 32767 | |
+
| i32 | 4 | -2147483648 to 2147483647 | |
+
| i64 | 8 | -9223372036854775808 to 9223372036854775807 | |
+
| f32 | 4 | See [here][java8spec_floating]. | Single-precision 32-bit IEEE754 floating point. |
+
| f64 | 8 | See [here][java8spec_floating]. | Double-precision 64-bit IEEE754 floating point. |
+
| str8 | >=2 | N/A | [Modified UTF-8][mutf8] string. Prefixed by an `i16` containing the length of the string **in bytes**. |
+
| str16 | >=2 | Minimum length of `0`, maximum character length of `32767` | [UTF-16][utf16] string. Prefixed by an `i16` containing the length of the string **in characters**. |
+
| bool | 1 | `0x00` (`false`) or `0x01` (`true`) | |
+
There are also additional types being used:
+
| ID | Entity | Category | LivingEntity |
+
| --- | ------------- | ---------- | ------------ |
+
| 1 | Item | Misc | ❌ |
+
| 9 | Painting | Misc | ❌ |
+
| 10 | Arrow | Projectile | ❌ |
+
| 11 | Snowball | Projectile | ❌ |
+
| 20 | Primed TNT | Misc | ❌ |
+
| 21 | Falling Sand | Misc | ❌ |
+
| 40 | Minecart | Vehicle | ❌ |
+
| 41 | Boat | Vehicle | ❌ |
+
| 50 | Creeper | Hostile | ✅ |
+
| 51 | Skeleton | Hostile | ✅ |
+
| 52 | Spider | Hostile | ✅ |
+
| 53 | Giant | Hostile | ✅ |
+
| 54 | Zombie | Hostile | ✅ |
+
| 55 | Slime | Hostile | ✅ |
+
| 56 | Ghast | Hostile | ✅ |
+
| 57 | Zombie Pigman | Neutral | ✅ |
+
| 90 | Pig | Passive | ✅ |
+
| 91 | Sheep | Passive | ✅ |
+
| 92 | Cow | Passive | ✅ |
+
| 93 | Chicken | Passive | ✅ |
+
| 94 | Squid | Passive | ✅ |
+
| 95 | Wolf | Passive | ✅ |
+
Entity metadata has a quirky packing format.
+
A metadata field is a byte. The top three bits of the byte, when masked off
+
(`(byte & 224) >> 5`) and interpreted as a three-bit number from 0 to 7,
+
indicate the type of the field.
+
The lower five bits are unused. The type of the byte indicates the size and
+
type of a payload which follows the initial byte of the field.
+
The metadata format consists of at least one field, followed by either another
+
field or the magic number `0x7F`. `0x7F` terminates a metadata stream.
+
Thus, the example metadata stream `0x00 0x01 0x7f` is decoded as a field of
+
type 0, id 0, with a payload of byte 0x00.
+
| Field ID | Field Type |
+
| -------- | ------------------------------------------- |
+
| 4 | str16 (maximum character length of 64) |
+
| 5 | ItemStack; `i16` ID, `i8` count, `i16` data |
+
| 6 | Vector of `i32`, 3 long (x,y,z) |
+
More information is available at [0x18 Spawn Living Entity][spawn_living_entity].
+
Sent as an `i32` on the wire, but is actually an `f64`.
+
public static int floorDouble(double aDouble) {
+
int anInteger = (int)aDouble;
+
return aDouble < (double)anInteger ? anInteger - 1 : anInteger;
+
Sent as an `i8` on the wire, but is actually an `f32`.
+
Basically, takes a rotation in degrees (`0..360`) and maps it into `0..255`.
+
public static byte packRotation(float rotation) {
+
return (byte)((int)(rotation * 256.0F / 360.0F))
+
Sent as an `i8` on the wire, but is actually an `f64`.
+
Basically, just multiply the value by `128` and turn it into a (signed) byte.
+
public static byte packMotion(double motion) {
+
return (byte)((int)(motion * 128.0D))
+
Sent as an `i16` on the wire, but is actually an `f64`.
+
Basically, just multiply the value by `128` and turn it into a (signed) byte.
+
public static byte packMotion(double motion) {
+
return (byte)((int)(motion * 128.0D))
+
This packet must be sent to keep the connection alive.
+
- Keep Alive has no payload.
+
- Size: 15 + length of strings
+
Sent by the server if it accepts the client's login request. If it didn't it
+
will send a [Disconnect][disconnect] instead.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | --------------------------------------------------------------------------- |
+
| Entity ID | i32 | `14` | The protocol version of Beta 1.7 is 14 |
+
| Unused | str16 | N/A | Unused by the client. Vanilla server sends an empty string |
+
| Map Seed | i64 | `0` | Used by the client to determine its current biome, among a few other things |
+
| Dimension | i8 | `0` | `-1` for the Nether, `0` for the Overworld |
+
Sent by the client after the handshake to finish logging in.
+
| Field Name | Field Type | Example | Notes |
+
| ---------------- | ---------- | ------------- | ------------------------------------------------------------------------------- |
+
| Protocol version | i32 | `14` | The protocol version of Beta 1.7 is 14 |
+
| Username | str16 | `kokiriglade` | The name of the player attempting to login. Max length of 16 |
+
| Map Seed | i64 | `0` | Can be safely ignored by the server |
+
| Dimension | i8 | `0` | `-1` for the Nether, `0` for the Overworld. Can be safely ignored by the server |
+
- Size: 2 + length of strings
+
| Field Name | Field Type | Example | Notes |
+
| --------------- | ---------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+
| Connection Hash | str16 | `2e66f1dc032ab5f0` | A unique, per-connection hash. The vanilla server sends a random `i64` stringified as a hexadecimal number. For offline-mode, the string is always a single `-` |
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------------- | ---------------------------------------------------------------------------- |
+
| Username | str16 | `kokiriglade` | The name of the player attempting to connect. Maximum character length of 16 |
+
- Size: 2 + length of strings
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ---------------------- | ----------------------------------------------------------------------------- |
+
| Message | str16 | `<kokiriglade> Hello!` | The name of the player attempting to connect. Maximum character length of 119 |
+
The time of day is based on `timestamp % 24000`, where:
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ----------------------- |
+
| Time | i64 | | The world time in ticks |
+
## 0x05 Set Player Equipment
+
After each [player spawn][spawn_player], there will be five of these packets for
+
the equipped item and armor. If there are changes in visible equipment, another
+
one of these packets is sent.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------------------------ |
+
| Entity ID | i32 | | Player's entity ID |
+
| Slot | i16 | `4` | Equipment slot. See below |
+
| Item ID | i16 | `-1` | Equipped item (`-1` for aempty slot) |
+
| Data | i16 | | Item data value |
+
(These only apply to this packet)
+
Sent after login to specify the coordinates of the spawn point (the location at
+
which players spawn, and which the compass points to).
+
It can be sent at any time to update the point compasses point to.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ---------------------------- |
+
| X | i32 | `117` | Spawn X in block coordinates |
+
| Y | i32 | `70` | Spawn Y in block coordinates |
+
| Z | i32 | `-46` | Spawn Z in block coordinates |
+
Sent upon attacking or right clicking an entity.
+
| Field Name | Field Type | Example | Notes |
+
| ---------------- | ---------- | ------- | ----------------------------------------------------------------------- |
+
| Entity ID | i32 | | Player's entity ID. Ignored by the server |
+
| Target entity ID | i32 | | Entity ID of the entity being interacted with |
+
| Left click | bool | `true` | `true` if the interaction was caused by a left click, `false` otherwise |
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ---------------- |
+
| Health | i16 | `20` | Half a heart = 1 |
+
Sent by the client when the player presses the "Respawn" button after dying.
+
The server then teleports the player to the spawn point, and sends a respawn
+
packet in response. The client will not leave the respawn screen until it
+
receives a respawn packet.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------------------------------------------------------------------- |
+
| Dimension | i8 | `0` | `-1` for the Nether, `0` for the Overworld. Can be safely ignored by the server |
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | -------------------------------------------------------- |
+
| On Ground | bool | `true` | `true` if the player is on the ground, `false` otherwise |
+
## 0x0B Player Position
+
Updates the player position on the server. If `(stance - y) < 0.1 || (stance - y) > 1.65`
+
then the stance is illegal.
+
If the distance between the last known position of
+
the player and the new position set by this packet is greater than 100, then the
+
If the absolute number of `x` or `z` are set greater than `3.2E7` then the
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | --------- | ----------------------------------------------------------------------------- |
+
| X | f64 | `102.809` | |
+
| Y | f64 | `70.00` | |
+
| Stance | f64 | `71.62` | Used to modify the players bounding box when going up stairs, crouching, etc. |
+
| Z | f64 | `68.30` | |
+
| On Ground | bool | `true` | `true` if the player is on the ground, `false` otherwise |
+
Updates the direction the player is looking in.
+
Yaw is measured in degrees, and does not follow classical trigonometry rules.
+
The unit circle of yaw on the xz-plane starts at (0, 1) and turns backwards
+
towards (-1, 0), or in other words, it turns clockwise instead of
+
counter-clockwise. Additionally, yaw is not clamped to between 0 and 360
+
degrees; any number is valid, including negative numbers and numbers greater
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | -------------------------------------------------------- |
+
| Yaw | f32 | `0.0` | Rotation on the X Axis, in degrees |
+
| Pitch | f32 | `0.0` | Rotation on the Y axis, in degrees |
+
| On Ground | bool | `true` | `true` if the player is on the ground, `false` otherwise |
+
## 0x0D Player Position and Look
+
A combination of [Player Look][player_look] and [Player Position][player_position].
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | --------- | ----------------------------------------------------------------------------- |
+
| X | f64 | `102.809` | |
+
| Y | f64 | `70.00` | |
+
| Stance | f64 | `71.62` | Used to modify the players bounding box when going up stairs, crouching, etc. |
+
| Z | f64 | `68.30` | |
+
| Yaw | f32 | `0.0` | Rotation on the X Axis, in degrees |
+
| Pitch | f32 | `0.0` | Rotation on the Y axis, in degrees |
+
| On Ground | bool | `true` | `true` if the player is on the ground, `false` otherwise |
+
Sent when the player is digging a block.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------------------------------------------------- |
+
| Status | i8 | `1` | The action the player is taking against the block (see below) |
+
| X | i32 | `32` | Block position |
+
| Y | i8 | `64` | Block position |
+
| Z | i32 | `32` | Block position |
+
| Face | i8 | `3` | The face being hit (see below) |
+
- `2`: Finished digging
+
For some unthinkable reason, when the player drops an item, it sends this packet
+
but the status is `4`, and all other values are `0`.
+
Sent when the player places a block or (probably) an item. The coordinates sent
+
in this packet are actually the block being built against, which combined with
+
the direction offset tell you where the block should be placed. This is
+
required to correctly position furnaces, torches, etc.
+
| Field Name | Field Type | Example | Notes |
+
| ---------------- | ------------- | ------- | ---------------------------------------------------------- |
+
| X | i32 | `32` | Block position |
+
| Y | i8 | `64` | Block position |
+
| Z | i32 | `32` | Block position |
+
| Face | i8 | `3` | The face being placed against (see [Block Dig][block_dig]) |
+
| Block or Item ID | i16 | `1` | The block or item to be placed |
+
| Count | Optional<i8> | `34` | The count of the itemstack in the players hand |
+
| Data | Optional<i16> | `83` | The data value of the itemstack |
+
If the Block/ItemID field is greater than or equal to 0, then the last
+
2 fields (count and data) are read. Otherwise, they are not read.
+
When 'placing' (Or more accurately, using) your empty hand, the client sends -1
+
This packet has a special case where X, Y, Z, and Direction are all -1.
+
This special packet indicates that the currently held item for the player should
+
have its state updated such as eating food, shooting bows, using buckets, etc.
+
When using buckets, the client might send two packets: first a normal and then a
+
special case. The first normal packet is sent when you're looking at a block
+
(e.g. the water you want to scoop up). This normal packet does not appear to do
+
anything with a Vanilla server. The second, special case packet appears to
+
perform the action - based on current position/orientation and with a distance
+
check - it appears that buckets can only be used within a radius of 6 blocks.
+
## 0x10 Change Current Slot
+
Sent when the player changes their current/active slot.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | --------------------------------- |
+
| Slot ID | i16 | `1` | Valid values are 0..8 (inclusive) |
+
Sent to indicate a player is sleeping in a bed.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------ |
+
| Entity ID | i32 | `89` | Player's entity ID |
+
| Unknown | i8 | `0` | Always 0, unused |
+
| X | i32 | `-247` | Block coordinate |
+
| Y | i8 | `78` | Block coordinate |
+
| Z | i32 | `128` | Block coordinate |
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------ |
+
| Entity ID | i32 | `55534` | Player's entity ID |
+
| Animate | i8 | `1` | See below |
+
- `2`: Damage animation
+
Sent when crouching and leaving a bed.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------ |
+
| Entity ID | i32 | `55534` | Player's entity ID |
+
| Action | i8 | `1` | See below |
+
- Size: 22 + length of strings
+
Sent when a player comes into visible range. The vanilla client is not okay
+
with receiving player entity packets that refer to its own username or EID; it
+
will teleport to the absolute origin of the map and fall through the void any
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------------- | --------------------------------------------------------------------- |
+
| Entity ID | i32 | `94453` | Player's entity ID |
+
| Name | str16 | `kokiriglade` | Maximum character length of 16 |
+
| X | i32 | `102.809` | [Packed f64][packed_f64] |
+
| Y | i32 | `70.00` | [Packed f64][packed_f64] |
+
| Z | i32 | `68.30` | [Packed f64][packed_f64] |
+
| Yaw | i8 | `0.0` | [Packed rotation][packed_rotation] |
+
| Pitch | i8 | `0.0` | [Packed rotation][packed_rotation] |
+
| Held Item | i16 | `0` | The item the player is holding. `0` for no item. Must not be negative |
+
Sent when a thrown item comes into range of the player.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | --------- | ------------------------------------ |
+
| Entity ID | i32 | `157617` | Item's entity ID |
+
| Item ID | i16 | `4` | |
+
| Count | i8 | `1` | The count of the itemstack |
+
| Data | i16 | Item data | |
+
| X | i32 | `102.809` | [Packed f64][packed_f64] |
+
| Y | i32 | `70.00` | [Packed f64][packed_f64] |
+
| Z | i32 | `68.30` | [Packed f64][packed_f64] |
+
| Motion X | i8 | `0.0` | [Packed motion-i8][packed_motion_i8] |
+
| Motion Y | i8 | `0.0` | [Packed motion-i8][packed_motion_i8] |
+
| Motion Z | i8 | `0.0` | [Packed motion-i8][packed_motion_i8] |
+
Sent when someone picks up an item lying on the ground - its sole purpose is
+
the animation of the item flying towards the player.
+
It doesn't destroy the entity in the client memory ([Destroy Entity][destroy_entity]
+
does that), and it doesn't add it to the player's inventory ([Set Slot][set_slot]
+
The server only checks for items to be picked up after each [Player Position][player_position]
+
and [Player Position and Look][player_position_and_look] packet sent by the client.
+
| Field Name | Field Type | Example | Notes |
+
| ------------------- | ---------- | ------- | -------------------------- |
+
| Collected Entity ID | i32 | `28` | Collected item's entity ID |
+
| Collector Entity ID | i32 | `30` | Collector's entity ID |
+
## 0x17 Spawn Non-Living Entity
+
Sent when a Non-Living entity is created.
+
| Field Name | Field Type | Example | Notes |
+
| ----------- | ---------- | ------- | ---------------------------------------------------------------- |
+
| Entity ID | i32 | `62` | |
+
| Entity Type | i8 | `11` | [See Entity Types][entity_types] (must be of kind `Living`) |
+
| X | i32 | `16080` | [Packed f64][packed_f64] |
+
| Y | i32 | `2290` | [Packed f64][packed_f64] |
+
| Z | i32 | `592` | [Packed f64][packed_f64] |
+
| Has Motion | i32 | `0` | If this flag is bigger than 0 then the following fields are sent |
+
| Motion X | i16 | `0` | [Packed motion-i16][packed_motion_i16] |
+
| Motion Y | i16 | `0` | [Packed motion-i16][packed_motion_i16] |
+
| Motion Z | i16 | `0` | [Packed motion-i16][packed_motion_i16] |
+
## 0x18 Spawn Living Entity
+
- Size: 19 + [Metadata][entity_metadata] (at least 1)
+
Sent when a Living Entity is created.
+
| Field Name | Field Type | Example | Notes |
+
| ------------------ | ---------------------------------- | ------- | -------------------------------------------------- |
+
| Entity ID | i32 | `62` | |
+
| Living Entity Type | i8 | `11` | See below |
+
| X | i32 | `16080` | [Packed f64][packed_f64] |
+
| Y | i32 | `2290` | [Packed f64][packed_f64] |
+
| Z | i32 | `592` | [Packed f64][packed_f64] |
+
| Yaw | i8 | `-27` | [Packed rotation][packed_rotation] |
+
| Pitch | i8 | `0` | [Packed rotation][packed_rotation] |
+
| Entity Metadata | [Entity Metadata][entity_metadata] | `127` | Indexed metadata, terminated by `0x7F` - see below |
+
### Living Entity types
+
- Index 16 is `i8`, for `fuse`
+
- `1` for blowing up, `-1` otherwise
+
- Index 17 is `bool`, for `is charged`
+
- Index 16 is `i8`, for `size`
+
- Index 16 is `i8`, for `is attacking`
+
- Index 16 is `i8`, for `is saddled`
+
- Index 16 is `i8` for `coat`
+
- You can use a `0x10` bit mask for `shearedness` and `0x0F` for `color` - see below
+
- Index 16 is `i8`, and is a bitmask:
+
- `0x01` for `is sitting`
+
- `0x02` for `is aggressive`
+
- `0x04` for `is tamed`
+
- Index 17 is `string16`, and is the `name of the player` who tamed the wolf
+
- Index 18 is `i32`, and is the `health` of the wolf
+
Metadata index 0 is an `i8` representing a set of 8 `bool`s:
+
- `8`: Light Gray (Silver)
+
- Size: 22 + length of strings
+
Sent when a painting is created.
+
Calculating the center of an image: given a `(width x height)` grid of cells,
+
with `(0, 0)` being the top left corner, the center is `(max(0, width / 2 - 1), height / 2)`.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ---------- | ---------------------------------------------------- |
+
| Entity ID | i32 | `326` | |
+
| Title | str16 | `Creepers` | Name of the painting. Maximum character length of 13 |
+
| X | i32 | `50` | Center X coordinate |
+
| Y | i32 | `66` | Center Y coordinate |
+
| Z | i32 | `-50` | Center Z coordinate |
+
| Direction | i32 | `0` | Direction the painting is facing, see below |
+
## 0x1C Update Velocity
+
Velocity is believed to be in units of 1/32000 of a block per server tick
+
(200ms); for example, `-1343` would move `(-1343 / 32000) = -0.04196875` blocks
+
per tick (or `-0.20984375 blocks per second`).
+
Each axis' velocity is capped between -0.9 and 0.9 blocks per tick (packet
+
values -28800 to 28800).
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ---------------------- |
+
| Entity ID | i32 | `1805` | |
+
| X | i16 | `-1343` | Velocity on the X axis |
+
| Y | i16 | `0` | Velocity on the Y axis |
+
| Z | i16 | `0` | Velocity on the Z axis |
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ----- |
+
| Entity ID | i32 | `446` | |
+
Most entity-related packets are subclasses of this packet. When sent from the
+
server to the client, it may initialize the entry.
+
For player entities, either this packet or any move/look packet is sent several
+
times per second. So the meaning of this packet is basically that the entity
+
did not move/look since the last such packet.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ----- |
+
| Entity ID | i32 | `446` | |
+
## 0x1F Entity Relative Move
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ----- |
+
| Entity ID | i32 | `446` | |
+
| Relative X | i8 | `1` | |
+
| Relative Y | i8 | `-7` | |
+
| Relative Z | i8 | `5` | |
+
Solid documentation on what these relative coordinates actually are is kind of
+
lacking - apologies. I'll figure it out eventually though.
+
This packet is sent by the server when an entity rotates.
+
Example: `Yaw`=`64` means a 90 degree turn.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ---------------------------------- |
+
| Entity ID | i32 | `459` | |
+
| Yaw | i8 | `64` | [Packed rotation][packed_rotation] |
+
| Pitch | i8 | `0` | [Packed rotation][packed_rotation] |
+
## 0x21 Entity Look and Relative Move
+
This packet is sent by the server when an entity rotates and moves.
+
Since `i8` range is limited from -128 to 127, this packet allows at most four b
+
locks movement in any direction. (`-128/32 == -4`)
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------------------------ |
+
| Entity ID | i32 | `446` | |
+
| Relative X | i8 | `1` | |
+
| Relative Y | i8 | `-7` | |
+
| Relative Z | i8 | `5` | |
+
| Yaw | i8 | `64` | X axis rotation as a fraction of 360 |
+
| Pitch | i8 | `0` | Y axis rotation as a fraction of 360 |
+
## 0x22 Entity Teleport
+
This packet is sent by the server when an entity moves more than 4 blocks.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ---------------------------------- |
+
| Entity ID | i32 | `446` | |
+
| X | i32 | `14162` | [Packed f64][packed_f64] |
+
| Y | i32 | `2176` | [Packed f64][packed_f64] |
+
| Z | i32 | `1111` | [Packed f64][packed_f64] |
+
| Yaw | i8 | `64` | [Packed rotation][packed_rotation] |
+
| Pitch | i8 | `0` | [Packed rotation][packed_rotation] |
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | --------- |
+
| Entity ID | i32 | `446` | |
+
| Status | i8 | `2` | See below |
+
- `2`: (Living Entities only) Attack animation
+
- `3`: (Living Entities only) Death animation
+
- `6`: (Wolf only) Make smoke particles
+
- `7`: (Wolf only) Make hearts particles
+
- `8`: (Wolf only) Shaking
+
This packet is sent when a player starts riding an entity.
+
| Field Name | Field Type | Example | Notes |
+
| ----------------- | ---------- | ------- | ------------------- |
+
| Player Entity ID | i32 | `446` | Player's entity ID |
+
| Vehicle Entity ID | i32 | `1805` | Vehicle's entity ID |
+
## 0x28 Update Entity Metadata
+
- Size: 4 + [Metadata][entity_metadata] (at least 1)
+
| Field Name | Field Type | Example | Notes |
+
| --------------- | ---------------------------------- | ------- | ------------------------------------------------- |
+
| Entity ID | i32 | `446` | Entity ID |
+
| Entity Metadata | [Entity Metadata][entity_metadata] | `127` | Indexed metadata, terminated by `0x7F` - see link |
+
## 0x32 Initialize Chunk
+
The client is expected to allocate space for a full chunk (16 x 128 x 16 blocks).
+
One or more [Chunk Data][chunk_data] packets will follow, specifying actual data
+
to fill the chunk with.
+
Whenever you send this packet the client will clear any previous chunk at that
+
spot if one has previously been sent. Clients don't like being in or next to an
+
unloaded chunk, so try not to unload it if players are nearby. If the player
+
appears to be twitching and stuck in place after joining the world, there is
+
probably an unloaded chunk too close to them.
+
| Field Name | Field Type | Example | Notes |
+
| ----------- | ---------- | ------- | ------------------------------------------------------------------------------------- |
+
| X | i32 | `-9` | Chunk coordinate |
+
| Z | i32 | `12` | Chunk coordinate |
+
| Load/Unload | bool | `true` | If `false`, the client unloads the chunk. If `true`, the client initializes the chunk |
+
- Size: 17 + compressed chunk size
+
| Field Name | Field Type | Example | Notes |
+
| --------------- | ---------- | ------- | ------------------------------------- |
+
| X | i32 | `128` | Block coordinate |
+
| Y | i16 | `0` | Block coordinate |
+
| Z | i32 | `-192` | Block coordinate |
+
| Size X | i8 | `15` | Size X is Actual X Size -1 |
+
| Size Y | i8 | `127` | Size Y is Actual Y Size -1 |
+
| Size Z | i8 | `15` | Size Z is Actual Z Size -1 |
+
| Compressed size | i32 | `3663` | Size of compressed region data |
+
| Compressed data | Vec\<u8\> | `...` | Compressed region data (zlib deflate) |
+
This is the start position of the region, in world block coordinates.
+
To find which chunk is affected, in the same coordinates given by [Initialize Chunk][initialize_chunk]:
+
And conversely, which local block in the chunk to start at:
+
startY = Y & 127 (not always 0!)
+
This is the size of the region, in blocks. The server will subtract one from
+
the sizes and then cast them to a byte before sending. This is so that chunks
+
as large as 256 are possible.
+
The data is compressed using the deflate() function in [zlib]. After uncompressing,
+
the data consists of four sequential sections, in order:
+
- Block ID array (1 byte per block)
+
- Block metadata array (half byte/nibble per block)
+
- Block Light array (half byte/nibble per block)
+
- Sky Light array (half byte/nibble per block)
+
The data is exactly `(sizeX+1) * (sizeY+1) * (sizeZ+1) * 2.5` bytes long.
+
Nibbles are not rounded either direction, which means that at least one
+
dimension of the chunk must be even.
+
The arrays are not interlaced.
+
In other words, there are `sizeX` number of x planes, each plane made up of
+
`sizeZ` number of z rows, each row made up of `sizeY` blocks indexed by y
+
The Block ID array is indexed with:
+
index = y + (z * (sizeY+1)) + (x * (sizeY+1) * (sizeZ+1))
+
The other arrays are similar but you need to divide the index by two after
+
calculating the above. Then each byte contains data for two blocks. The low
+
four bits contain the first (lower Y) nibble and the high four bits contain the
+
If you have a FULL map chunk (`sizeX = 15, sizeY = 127, sizeZ = 15`), you can
+
calculate index coordinates:
+
x = X + ( index >> 11 )
+
z = Z + ( (index & 0x780) >> 7 )
+
## 0x34 Multi Block Change
+
This is a multiple-block-change command; if you take the three arrays, and put
+
together elements with the same index, and then decompose the `i16` into
+
coordinates (top 4 bits is X, next 4 bits is Z, bottom 8 bits is Y), you get
+
arrays like [((8, 7, 4), 11, 0), ((7, 13, 6), 11, 0), ((13, 1, 8), 11, 0), ((7, 6, 6), 11, 0)].
+
| Field Name | Field Type | Example | Notes |
+
| -------------------- | ---------- | ------- | --------------------------------------- |
+
| X | i32 | `-9` | Chunk coordinate |
+
| Z | i32 | `12` | Chunk coordinate |
+
| Array size | i16 | `2` | The total number of elements per array |
+
| Coordinate array | Vec\<i16\> | `...` | The coordinates of the blocks to change |
+
| Block ID array | Vec\<i8\> | `...` | The ID for each block to change |
+
| Block metadata array | Vec\<i8\> | `...` | The metadata for each block changed |
+
See [blocks] for information on the metadata variable.
+
| Field Name | Field Type | Example | Notes |
+
| -------------- | ---------- | ------- | -------------------------- |
+
| X | i32 | `128` | Block coordinate |
+
| Y | i8 | `0` | Block coordinate |
+
| Z | i32 | `-192` | Block coordinate |
+
| Block ID | i8 | `78` | The type for the block |
+
| Block metadata | i8 | `0` | The metadata for the block |
+
See [blocks] for information on the metadata variable.
+
## 0x36 Play Note Block
+
Sent when a note block is played.
+
| Field Name | Field Type | Example | Notes |
+
| --------------- | ---------- | ------- | ----------------------------------------------- |
+
| X | i32 | `128` | Block coordinate |
+
| Y | i16 | `0` | Block coordinate |
+
| Z | i32 | `-192` | Block coordinate |
+
| Instrument type | i8 | `3` | See below |
+
| Pitch | i8 | `17` | The pitch of the note (between 0..24 inclusive) |
+
- `3`: Clicks/Sticks (Hihat)
+
- Size: 32 + `3*(coordinate count)`
+
Sent when an explosion occurs.
+
| Field Name | Field Type | Example | Notes |
+
| ---------------- | --------------------- | -------- | ------------------------------ |
+
| X | f64 | `128.0` | Center coordinate |
+
| Y | f64 | `0.0` | Center coordinate |
+
| Z | f64 | `-192.0` | Center coordinate |
+
| Radius | f32 | `4.0` | |
+
| Coordinate count | i32 | `60` | |
+
| Records | (i8, i8, i8) \* count | `...` | XYZ offsets of affected blocks |
+
Sent when a client is to play an effect.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | -------- | ---------------- |
+
| Effect ID | i32 | `1003` | See below |
+
| X | i32 | `128.0` | Block coordinate |
+
| Y | i8 | `0.0` | Block coordinate |
+
| Z | i32 | `-192.0` | Block coordinate |
+
| Data | i32 | `0` | See below |
+
- `1000`: Play sound `random.click` with pitch 1.0
+
- `1001`: Play sound `random.click` with pitch 1.2
+
- `1002`: Play sound `random.bow` with pitch 1.2
+
- `1003`: Play sound randomly between `random.door_open` and `random.door_close` with random uniform pitch between 0.0 and 1.0
+
- `1004`: Play sound `random.fizz` with volume 0.5 and random pitch
+
- `1005`: Play record sound.
+
- The record item ID is given in the effect data.
+
- `2000`: Spawn smoke particles
+
- The radius is given in effect data with two bits for X and Z axis, like this: `0bZZXX`
+
- `2001`: Play and show block break sound and particles.
+
- The block id is given in effect data.
+
Sent to notify the client of some state.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | --------- |
+
| Reason | i8 | `1` | See below |
+
Notifies the client of thunderbolts striking somewhere. The coordinates specify
+
where exactly the thunderbolt strikes.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------- | ------------------------ |
+
| Entity ID | i32 | `4` | Lightning bolt entity ID |
+
| ??? | bool | `true` | Always `true` |
+
| X | i32 | `133` | [Packed f64][packed_f64] |
+
| Y | i32 | `913` | [Packed f64][packed_f64] |
+
| Z | i32 | `63552` | [Packed f64][packed_f64] |
+
- Size: 5 + length of strings
+
| Field Name | Field Type | Example | Notes |
+
| --------------- | ---------- | ------- | -------------------- |
+
| Inventory ID | i8 | `123` | |
+
| Inventory Type | i8 | `0` | See below |
+
| Title | str8 | `Chest` | Only used for chests |
+
| Number of slots | i8 | `3` | |
+
## 0x65 Close Inventory
+
Clients send this packet with Inventory ID `0` when they close their inventory.
+
| Field Name | Field Type | Example | Notes |
+
| ------------ | ---------- | ------- | ------------------------ |
+
| Inventory ID | i8 | `123` | 0 for player's inventory |
+
## 0x66 Click Inventory
+
Sent when the playuer clicks on a slot in an inventory.
+
| Field Name | Field Type | Example | Notes |
+
| -------------- | ---------- | ------- | ----------------------------------------------------------------------------------------------------- |
+
| Inventory ID | i8 | `123` | 0 for player's inventory |
+
| Cicked Slot | i16 | `36` | |
+
| Right clicking | bool | `true` | `true` if right cicking, `false` otherwise |
+
| Action number | `i16` | `12` | Unique number for the action, used for [transaction handling][transaction] |
+
| Shift | bool | `fase` | `true` if the player was holding shift, `false` otherwise |
+
| Item ID | `i16` | `3` | ID of the item that was in the slot. `-1` for no item. If `-1`, this is the last field in the packet. |
+
| Item Count | `i8` | `64` | |
+
| Item Data | `i16` | `10` | |
+
When right-clicking on a stack of items, half the stack will be picked up and
+
half left in the slot. If the stack is an odd number, the half left in the slot
+
will be smaller of the amounts.
+
The Action number is actually a counter, starting at `1`. This number is used by
+
the server as a transaction ID to send back a [transaction] packet.
+
For help with slot IDs, see the next packet.
+
## 0x67 Set Inventory Slot
+
Sent by the server when an item in a slot is added/removed.
+
| Field Name | Field Type | Example | Notes |
+
| ------------ | ---------- | ------- | ---------------------------------------------------------------- |
+
| Inventory ID | i8 | `123` | 0 for player's inventory |
+
| Slot | i16 | `36` | |
+
| Item ID | `i16` | `3` | `-1` for no item. If `-1`, this is the last field in the packet. |
+
| Item Count | `i8` | `64` | |
+
| Item Data | `i16` | `10` | |
+
Note that if window ID and slot are both `-1`, it means the item currently attached to the cursor.
+

+
## 0x68 Set Inventory Slots
+
- Size: 3 + size of payload
+
Sent by the server when items in slots are added/removed. This includes the
+
player inventory, equipped armor, and crafting slots.
+
| Field Name | Field Type | Example | Notes |
+
| ------------- | ---------- | ------- | ------------------------ |
+
| Inventory ID | i8 | `123` | 0 for player's inventory |
+
| Payload count | i16 | `4` | See below |
+
| Payload | ... | | See below |
+
This packet is a bit trickier to parse than most others because the size of its
+
payload is variable. The payload is an array of shorts (item ID) optionally
+
followed by a byte-short pair (count and data) as long as the item ID does not
+
equal `-1`, which signifies an empty slot.
+
item_id = payload[offset] as short
+
if item_id is not equal to -1:
+
count = payload[offset] as byte
+
uses = payload[offset] as short
+
inventory[slot] = new item(item_id, count, uses)
+
## 0x69 Update Progress Bar
+
| Field Name | Field Type | Example | Notes |
+
| ------------ | ---------- | ------- | ------------------------ |
+
| Inventory ID | i8 | `123` | 0 for player's inventory |
+
| Progress Bar | i16 | `1` | See below |
+
| Value | i16 | 650 | See below |
+
- `2`: Current Item Burn Time
+
- time in ticks that the fuel item takes to burn
+
- Full progress arrow: approx. `180`
+
- Full fire icon: approx. `250`
+
A packet from the server indicating whether a request from the client was
+
accepted, or whether there was a conflict (due to lag). This packet is also
+
sent from the client to the server in response to a server transaction rejection
+
| Field Name | Field Type | Example | Notes |
+
| ------------- | ---------- | ------- | ------------------------ |
+
| Inventory ID | i8 | `123` | 0 for player's inventory |
+
| Action Number | i16 | `12` | |
+
| Accepted | bool | `true` | |
+
- Size: 10 + length of strings
+
This message is sent from the server to the client whenever a sign comes into
+
view distance or created. This message is sent from the client to the server when the "Done"
+
button is pressed after placing a sign.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | ------------- | ----- |
+
| Text1 | str16 | `First line` | |
+
| Text2 | str16 | `Second line` | |
+
| Text3 | str16 | `Third line` | |
+
| Text4 | str16 | `Fourth line` | |
+
- Size: 5 + length of payload
+
Sends map updates (columns of pixels or decorations).
+
It allows the server to stream partial changes to a map rather than the entire
+
| Field Name | Field Type | Example | Notes |
+
| -------------- | ---------- | ------- | --------- |
+
| Item ID | i16 | `358` | |
+
| Item Data | i16 | `0` | |
+
| Payload length | u8 | `35` | |
+
| Payload | Vec\<i8\> | `...` | See below |
+
The first byte of the payload is a _tag_ indicating the type of update:
+
#### Tag `0` (Column update)
+
- `u8 x_start`: X coordinate (0..127) of the column.
+
- `u8 y_start`: Y coordinate (0..127) of the starting pixel.
+
- `Vec<u8> colors`: Palette indices (one per pixel) written _downwards_ starting at `(x_start, y_start)`.
+
Each color is a raw color (0–255), not a limited palette enum. The raw value is
+
`base_id * 4 + shade`, where:
+
- `base_id` is one of the 14 map palette entries.
+
- `shade` is 0..3 for brightness variation.
+
#### Tag `1` (Decorations)
+
Sequence of entries, each 3 bytes:
+
- `u8 data`: Upper 4 bits = direction (0..15), lower 4 bits = type (always 0).
+
- `u8 x`: X coordinate of the decoration on the map (0..127).
+
- `u8 y`: Y coordinate of the decoration on the map (0..127).
+
Decorations are only used to show the player cursors on the map in Beta 1.7.
+
## 0xC8 Increment Statistic
+
| Field Name | Field Type | Example | Notes |
+
| ------------ | ---------- | ------- | --------------------- |
+
| Statistic ID | i32 | `1003` | See below |
+
| Amount | i8 | `1` | Negative to decrement |
+
- TODO :-( - but you can [try this forum post][statistics]?
+
- Size: 2 + length of strings
+
Sent by the server before it disconnects a client, or by the client before it
+
disconnects from the server. The receiver of this packet assumes that the
+
sender has already closed the connection by the time the packet arrives.
+
| Field Name | Field Type | Example | Notes |
+
| ---------- | ---------- | --------------------- | ----- |
+
| Reason | str16 | `The server is full!` | |
+
[entity_metadata]: #entity-metadata
+
[packed_f64]: #floored-double
+
[packed_rotation]: #packed-rotation
+
[packed_motion_i8]: #packed-motion-i8
+
[packed_motion_i16]: #packed-motion-i16
+
[entity_types]: #entity-types
+
[player_position]: #0x0b-player-position
+
[player_look]: #0x0c-player-look
+
[player_position_and_look]: #0x0d-player-position-and-look
+
[block_dig]: #0x0e-block-dig
+
[spawn_player]: #0x14-spawn-player
+
[spawn_living_entity]: #0x18-spawn-living-entity
+
[destroy_entity]: #0x1d-destroy-entity
+
[initialize_chunk]: #0x32-initialize-chunk
+
[chunk_data]: #0x33-chunk-data
+
[set_slot]: #0x67-set-slot
+
[transaction]: #0x6a-transaction
+
[disconnect]: #0xff-disconnect
+
[statistics]: http://www.minecraftforum.net/viewtopic.php?f=1020&t=295360
+
[zlib]: http://www.zlib.net/
+
[java8spec_floating]: https://docs.oracle.com/javase/specs/jls/se9/html/jls-4.html#jls-4.2.3
+
[utf16]: https://en.wikipedia.org/wiki/UTF-16
+
[mutf8]: https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8