Difference between revisions of "Protocol"
Barneygale (talk | contribs) |
|||
Line 665: | Line 665: | ||
You can get a unit vector from a given yaw/pitch via: | You can get a unit vector from a given yaw/pitch via: | ||
− | x = - | + | x = -cos(pitch) * sin(yaw) |
− | y = - | + | y = -sin(pitch) |
− | z = | + | z = cos(pitch) * cos(yaw) |
{| class="wikitable" | {| class="wikitable" |
Revision as of 16:10, 7 November 2011
This page presents a dissection of the current stable Minecraft Beta protocol. The current pre-release protocol is documented elsewhere.
Credit goes to the Great Old Ones, and the citizens of #mcdevs who helped by providing packet dumps and insight. If you're having trouble, check out the FAQ.
Note: While you may use the contents of this page without restriction to create servers, clients, bots, etc… you still need to provide the attribution above if you copy any of the contents of this page for publication elsewhere.
The protocol for Pocket Minecraft is substantially different, and is documented at Pocket Minecraft Protocol.
Contents
- 1 Data Types
- 2 Terminology
- 3 Units of Measurement
- 4 Packets
- 4.1 Keep Alive (0x00)
- 4.2 Login Request (0x01)
- 4.3 Handshake (0x02)
- 4.4 Chat Message (0x03)
- 4.5 Time Update (0x04)
- 4.6 Entity Equipment (0x05)
- 4.7 Spawn Position (0x06)
- 4.8 Use Entity (0x07)
- 4.9 Update Health (0x08)
- 4.10 Respawn (0x09)
- 4.11 Player (0x0A)
- 4.12 Player Position (0x0B)
- 4.13 Player Look (0x0C)
- 4.14 Player Position & Look (0x0D)
- 4.15 Player Digging (0x0E)
- 4.16 Player Block Placement (0x0F)
- 4.17 Holding Change (0x10)
- 4.18 Use Bed (0x11)
- 4.19 Animation (0x12)
- 4.20 Entity Action (0x13)
- 4.21 Named Entity Spawn (0x14)
- 4.22 Pickup Spawn (0x15)
- 4.23 Collect Item (0x16)
- 4.24 Add Object/Vehicle (0x17)
- 4.25 Mob Spawn (0x18)
- 4.26 Entity: Painting (0x19)
- 4.27 Experience Orb (0x1A)
- 4.28 Stance update (?) (0x1B)
- 4.29 Entity Velocity (0x1C)
- 4.30 Destroy Entity (0x1D)
- 4.31 Entity (0x1E)
- 4.32 Entity Relative Move (0x1F)
- 4.33 Entity Look (0x20)
- 4.34 Entity Look and Relative Move (0x21)
- 4.35 Entity Teleport (0x22)
- 4.36 Entity Status (0x26)
- 4.37 Attach Entity (0x27)
- 4.38 Entity Metadata (0x28)
- 4.39 Entity Effect (0x29)
- 4.40 Remove Entity Effect (0x2A)
- 4.41 Experience (0x2B)
- 4.42 Pre-Chunk (0x32)
- 4.43 Map Chunk (0x33)
- 4.44 Multi Block Change (0x34)
- 4.45 Block Change (0x35)
- 4.46 Block Action (0x36)
- 4.47 Explosion (0x3C)
- 4.48 Sound effect (0x3D)
- 4.49 New/Invalid State (0x46)
- 4.50 Thunderbolt (0x47)
- 4.51 Open window (0x64)
- 4.52 Close window (0x65)
- 4.53 Window click (0x66)
- 4.54 Set slot (0x67)
- 4.55 Window items (0x68)
- 4.56 Update progress bar (0x69)
- 4.57 Transaction (0x6A)
- 4.58 Creative inventory action (0x6B)
- 4.59 Update Sign (0x82)
- 4.60 Item Data (0x83)
- 4.61 Increment Statistic (0xC8)
- 4.62 Player List Item (0xC9)
- 4.63 Server List Ping (0xFE)
- 4.64 Disconnect/Kick (0xFF)
- 5 Protocol History
Data Types
All types in Java (and as such Minecraft) are big-endian, that is, the most significant byte comes first. The majority of everyday computers are little endian, and using most programming languages will require converting big endian values to little endian.
These data formats are identical to those provided by the Java classes DataInputStream and DataOutputStream.
Size | Range | Notes | |
---|---|---|---|
byte | 1 | -128 to 127 | Signed, two's complement |
short | 2 | -32768 to 32767 | Signed, two's complement |
int | 4 | -2147483648 to 2147483647 | Signed, two's complement |
long | 8 | -9223372036854775808 to 9223372036854775807 | Signed, two's complement |
float | 4 |
See this |
Single-precision 32-bit IEEE 754 floating point |
double | 8 |
See this |
Double-precision 64-bit IEEE 754 floating point |
string16 | ≥ 2 ≤ 240 |
N/A | UCS-2 string, big-endian. Prefixed by a short containing the length of the string in characters. UCS-2 consists of 16-bit words, each of which represent a Unicode code point between U+0000 and U+FFFF inclusive. |
bool | 1 | 0 or 1 | Value can be either True (0x01) or False (0x00) |
metadata | Varies | See this |
Terminology
This is a fairly lengthy page, and to make it more readable certain terminology must be understood. Terms used on this page and their definition are provided below.
Definition | |
---|---|
Player | When used in in the singular, Player always refers to the client connected to the server |
Entity | Entity refers to any item, player, mob, minecart or boat in the world. This definition is subject to change as Notch extends the protocol |
EID | An EID - or Entity ID - is a unique 4-byte integer used to identify a specific entity |
XYZ | In this document, the axis names are the same as those used by Notch. Y points upwards, X points South, and Z points West. |
Units of Measurement
There are several different units of measurement used in the protocol depending on what is being described. For example, it wouldn't make much sense to send the position of a block (which is a constant multiple of 32) in a floating point double.
A block represents 1 meter x 1 meter x 1 meter. There are 32 pixels per meter, and chunks are 16m x 128m x 16m.
Data Types | Units | Represents | |
---|---|---|---|
Absolute | double | meters | Represents an object's location in the world. |
Absolute Integer | int | pixels | Represents an object's location in the world. Functions the same as Absolute Double, but requires fewer bytes and is less precise. In C/C++/Java: absolute_int = (int)(absolute_double * 32.0);
|
Block | byte, short, int | meters | Represents a block's location in the world. |
Chunk | short, int | chunks | Represents the position of a chunk. |
Packets
All packets begin with a single "Packet ID" byte. Listed packet size includes this byte. Packets are either "server to client", "client to server", or both. If not specified, assume that the packet can be sent both ways. There is no "length" field; for variable length packets, you must parse to the end to determine the length.
Keep Alive (0x00)
The server will frequently send out a keep-alive, each containing a random ID. The client must respond with the same packet. The Beta server will disconnect a client if it doesn't receive at least one packet before 1200 in-game ticks, and the Beta client will time out the connection under the same conditions. The client may send packets with Keep-alive ID=0.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x00 | Keep-alive ID | int | 957759560
|
Server-generated random id |
Total Size: | 5 bytes |
Login Request (0x01)
Client to Server
Sent by the client after the handshake to finish logging in. If the version is outdated or any field is invalid, the server will disconnect the client with a kick. If the client is started in offline mode, the player's username will default to Player
, making LAN play with more than one player impossible (without authenticating) as the server will prevent multiple users with the same name.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x01 | Protocol Version | int | 20
|
1.8.1's protocol version is 17
|
Username | string16 | TkTech
|
The name of the user attempting to login, max length of 16 | |
Not used | long | 0
|
||
Not used | int | 0
|
||
Not used | byte | 0
|
||
Not used | byte | 0
|
||
Not used | unsigned byte | 0
|
||
Not used | unsigned byte | 0
|
||
Total Size: | 23 bytes + length of strings |
Server to Client
Sent by the server if it accepts the clients login request. If it didn't, it'll send a kick instead.
Max players is used by the client to draw the player list. Setting this value lower than the actual max players, or indeed the number of players online, will only affect the size and number of users displayed. Values above 127 will cause the player list not to be drawn. Values above 60 will cause usernames to overlap and not fit in their bounding boxes.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x01 | Entity ID | int | 1298
|
The Players Entity ID |
Not used | string16 | (empty string) | Not used | |
Map Seed | long | 971768181197178410
|
The server's map seed. Must be sent in respawn packets by the client. | |
Server mode | int | 0
|
0 for survival, 1 for creative | |
Dimension | byte | 0
|
Used for specifying the players dimension -1 for hell, 0 otherwise | |
Difficulty | byte | 1
|
0 thru 3 for Peaceful, Easy, Normal, Hard
| |
World height | unsigned byte | 128
|
Defaults to 128
| |
Max players | unsigned byte | 8
|
Used by the client to draw the player list | |
Total Size: | 23 bytes + length of strings |
Handshake (0x02)
Client to Server
This is the first packet sent when the client connects and is used for Authentication.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x02 | Username | string16 | TkTech
|
The username of the player attempting to connect, max length of 16 |
Total Size: | 3 bytes + length of strings |
Server to Client
This is the first packet sent when the client connects and is used for Authentication.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x02 | Connection Hash | string16 | 2e66f1dc032ab5f0
|
A unique, per-connection hash, or '-', or '+' |
Total Size: | 3 bytes + length of strings |
Possible values for Connection Hash:
Value | Meaning: What the client will do |
---|---|
The string '-' | No Auth: The client continues without doing name authentication. |
The string '+' | Password Auth: There is currently no way to send a password in at least version 1.8.1. It should be treated similarly to '-'. |
Anything else, will be a randomly generated long as a string of hex digits | Name Auth with minecraft.net: This hash, as of the latest version of the Beta server, is a randomly generated long in hexadecimal form, and has nothing to do with the client or the server it is connected to. The client proceeds to use this hash to log in via minecraft.net. |
Chat Message (0x03)
A message from the client to the server, or the server to the client. The actual handling of chat messages is variable and depends on the server and client; there are no de facto standards yet.
The Alpha server will check the message to see if it begins with a '/'. If it doesn't, the username of the sender is prepended and sent to all other clients (including the original sender). If it does, the server assumes it to be a command and attempts to process it. A message longer than 100 characters will cause the server to kick the client. This limits the chat message packet length to 103 bytes. Note that this limit does not apply to incoming chat messages as the server may have prepended other information, not limited to, but usually including, a username.
A message longer than 119 characters will cause the Beta (≥1.5) server and client to crash to print the message "Received string length longer than maximum allowed (X > 119)", with no side effects.
For more information, see Chat.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x03 | Message | string16 | <Bob> Hello World!
|
User input must be sanitized server-side |
Total Size: | 3 bytes + length of strings |
Time Update (0x04)
Server to Client only
Time is based on ticks, where 20 ticks happen every second. There are 24000 ticks in a day, making Minecraft days exactly 20 minutes long.
The time of day is based on the timestamp modulo 24000. 0 is sunrise, 6000 is noon, 12000 is sunset, and 18000 is midnight.
The default SMP server increments the time by 20
every second.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x04 | Time | long |
|
The world (or region) time, in ticks |
Total Size: | 9 bytes |
Entity Equipment (0x05)
After each "Named Entity Spawn", there will be five of these packets for the equipped item and armor. If there are changes in visible equipment, another one of these is sent.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x05 | Entity ID | int | 0x00010643 | Named Entity ID |
Slot | short | 4 | Equipment slot: 0=held, 1-4=armor slot | |
Item ID | short | -1 | Equipped item (-1 for empty slot) | |
Damage | short | |||
Total Size: | 11 bytes |
Spawn Position (0x06)
Server to Client only
Sent by the server after login to specify the coordinates of the spawn point (the point at which players spawn at, and which the compass points to). It can be sent at any time to update the point compasses point at.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x06 | X | int | 117
|
Spawn X in block coordinates |
Y | int | 70
|
Spawn Y in block coordinates | |
Z | int | -46
|
Spawn Z in block coordinates | |
Total Size: | 13 bytes |
Use Entity (0x07)
Client to Server only
This packet is new to version 4 of the protocol, and is believed to be Use Entity. This packet is sent from the client to the server when the client attacks or right-clicks another entity.
A Notchian server only accepts this packet if the entity being attacked/used is visible without obstruction and within a 4-unit radius of the player's position.
(This packet data values are not fully verified)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x07 | User | int | 1298
|
The entity of the player (ignored by the server) |
Target | int | 1805
|
The entity the player is interacting with | |
Left-click? | bool | true
|
Seems to be true when the player is pointing at an entity and left-clicking and false when right-clicking.
| |
Total Size: | 10 bytes |
Update Health (0x08)
Server to Client only
Sent by the server to update/set the health of the player it is sent to. Added in protocol version 5.
Food saturation acts as a food "overcharge". Food values will not decrease while the saturation is over zero. Players logging in automatically get a saturation of 5.0. Eating food increases the saturation as well as the food bar.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x08 | Health | short | 20 | 0 or less = dead, 20 = full HP |
Food | short | 20 | 0 - 20 | |
Food Saturation | float | 5.0 | Seems to vary from 0.0 to 5.0 in integer increments | |
Total Size: | 9 bytes |
Respawn (0x09)
Sent by the client when the player presses the "Respawn" button after dying. The server then teleports the user 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.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x09 | World | byte | 1
|
0 for standard world, -1 for nether.
|
Difficulty | byte | 1
|
0 thru 3 for Peaceful, Easy, Normal, Hard. 1 is always sent c->s
| |
Creative mode | byte | 1
|
0 for survival, 1 for creative.
| |
World height | short | 128
|
Defaults to 128
| |
Map Seed | long | -3815848935435401459
|
||
Total Size: | 14 bytes |
Player (0x0A)
Client to Server only
This packet is used to indicate whether the player is on ground (walking/swimming), or airborne (jumping/falling).
When dropping from sufficient height, fall damage is applied when this state goes from False to True. The amount of damage applied is based on the point where it last changed from True to False. Note that there are several movement related packets containing this state.
This packet was previously referred to as Flying
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0A | On Ground | bool | 1
|
True if the client is on the ground, False otherwise
|
Total Size: | 2 bytes |
Player Position (0x0B)
Client to Server (player-controlled movement).
Updates the players XYZ position on the server.
If Stance - Y
is less than 0.1
or greater than 1.65
, the stance is illegal and the client will be kicked with the message “Illegal Stance”.
If the distance between the last known position of the player on the server and the new position set by this packet has a distance greater than 100 units will result in the client being kicked for "You moved too quickly :( (Hacking?)"
Also if the absolute number of X or Z is set greater than 3.2E7D
the client will be kicked for "Illegal position"
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0B | X | double | 102.809
|
Absolute position |
Y | double | 70.00
|
Absolute position | |
Stance | double | 71.62
|
Used to modify the players bounding box when going up stairs, crouching, etc… | |
Z | double | 68.30
|
Absolute position | |
On Ground | bool | 1
|
Derived from packet 0x0A | |
Total Size: | 34 bytes |
Player Look (0x0C)
Client to Server (player-controlled movement).
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 counterclockwise. Additionally, yaw is not clamped to between 0 and 360 degrees; any number is valid, including negative numbers and numbers greater than 360.
Pitch is measured in degrees, where 0 is looking straight ahead, -90 is looking straight up, and 90 is looking straight down.
You can get a unit vector from a given yaw/pitch via:
x = -cos(pitch) * sin(yaw) y = -sin(pitch) z = cos(pitch) * cos(yaw)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0C | Yaw | float | 0.00
|
Absolute rotation on the X Axis, in degrees |
Pitch | float | 0.00
|
Absolute rotation on the Y Axis, in degrees | |
On Ground | bool | 1
|
Derived from packet 0x0A | |
Total Size: | 10 bytes |
Player Position & Look (0x0D)
A combination of Player Look and Player position.
Client to Server
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0D | X | double | 6.5
|
Absolute position |
Y | double | 65.620000004768372
|
Absolute position | |
Stance | double | 67.240000009536743
|
Used to modify the players bounding box when going up stairs, crouching, etc… | |
Z | double | 7.5
|
Absolute position | |
Yaw | float | 0.0
|
Absolute rotation on the X Axis | |
Pitch | float | 0.0
|
Absolute rotation on the Y Axis | |
On Ground | bool | 0
|
Derived from packet 0x0A | |
Total Size: | 42 bytes |
Server to Client
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0D | X | double | 6.5
|
Absolute position |
Stance | double | 67.240000009536743
|
Used to modify the players bounding box when going up stairs, crouching, etc… | |
Y | double | 65.620000004768372
|
Absolute position | |
Z | double | 7.5
|
Absolute position | |
Yaw | float | 0.0
|
Absolute rotation on the X Axis | |
Pitch | float | 0.0
|
Absolute rotation on the Y Axis | |
On Ground | bool | 0
|
Derived from packet 0x0A | |
Total Size: | 42 bytes |
Note that this packet differs from client Player & Position Look packet - the Stance and Y are sent in a different order.
Stance and Y seems to be the opposite as in the table (from Client to Server = X, Y, Stance, Z, froom Server to client = X, Stance, Y, Z) please confirm ! [BackBone`:] The opposite stance<->y confirmed, however the given structs had the server and client struct reversed, which I fixed.
When you connect to the official server, it will push a 0x0D packet. If you do not immediately respond with a 0x0D (or maybe 0x0A-0x0C) packet with similar and valid information, it will have unexpected results, such as map chunks not loading and future 0x0A-0x0D packets being ignored.
Player Digging (0x0E)
Sent when the player mines a block. A Notchian server only accepts digging packets with coordinates within a 6-unit radius of the player's position.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0E | Status | byte | 1
|
The action the player is taking against the block (see below) |
X | int | 32
|
Block position | |
Y | byte | 64
|
Block position | |
Z | int | 32
|
Block position | |
Face | byte | 3
|
The face being hit (see below) | |
Total Size: | 12 bytes |
Status can (currently) be one of four values:
Meaning | Value |
---|---|
Started digging | 0
|
Finished digging | 2
|
Drop item | 4
|
Shoot arrow | 5
|
Notchian clients send a 0 (started digging) when they start digging and a 2 (finished digging) once they think they are finished. If digging is aborted, no notice is sent to the server; the client simply does not send a 2 (finished digging).
Status code 4 (drop item) is a special case. In-game, when you use the Drop Item command (keypress 'q'), a dig packet with a status of 4, and all other values set to 0, is sent from client to server.
The face can be one of six values, representing the face being hit:
Value | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Offset | -Y | +Y | -Z | +Z | -X | +X |
In 1.7.3, when a player opens a door with left click the server receives Packet 0xE+start digging and opens the door.
Player Block Placement (0x0F)
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…
In 1.7.3, when a player opens a door with right click, the server receives Packet 0xF (block placement, but opens door).
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x0F | X | int | 32
|
Block position |
Y | byte | 64
|
Block position | |
Z | int | 32
|
Block position | |
Direction | byte | 3
|
The offset to use for block/item placement (see below) | |
Block or Item ID | short | 1
|
The block or item to be placed | |
Amount (opt) | byte | 34
|
The amount of the item in the players hand | |
Damage (opt) | short | 83
|
How much damage the item has taken | |
Total Size: | 13 bytes or 16 bytes |
If the Block/ItemID field is greater than or equal to 0, then the last 2 fields (amount and damage) are read. Otherwise, they are not read. When 'placing' (Or more accurately, using) your empty hand, the client sends -1 as the Block/ItemID
The direction can be one of six values, representing the face the block/item is being placed against:
Value | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Offset | -Y | +Y | -Z | +Z | -X | +X |
In normal operation (ie placing a block), this packet is sent once, with the values set normally.
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.
In a Notchian Beta client, the block or item ID corresponds to whatever the client is currently holding, and the client sends one of these packets any time a right-click is issued on a surface, so no assumptions can be made about the safety of the ID. However, with the implementation of server-side inventory, a Notchian server seems to ignore the item ID, instead operating on server-side inventory information and holding selection.
Special note on using buckets: When using buckets, the Notchian 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 Notchian 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 units.
Holding Change (0x10)
Sent when the player changes the slot selection
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x10 | Slot ID | short | 1
|
The slot which the player has selected (0-8) |
Total Size: | 3 bytes |
Use Bed (0x11)
Server to Client
Associated with players using beds.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x11 | Entity ID | int | 89 | Player ID |
???In Bed??? | byte | 0 | 0 Appears when players use bed | |
X coordinate | int | -247 | Bed (headboard?) X as block coordinate | |
Y coordinate | byte | 78 | Bed (headboard?) Y as block coordinate | |
Z coordinate | int | 128 | Bed (headboard?) Z as block coordinate | |
Total Size: | 15 bytes |
- NOTE: This Packet seems to be sent when 2 or more players are on a server, and at least one player uses a Bed.
Animation (0x12)
Sent whenever an entity should change animation.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x12 | EID | int | 55534
|
Player ID |
Animation | byte | 1
|
Animation ID | |
Total Size: | 6 bytes |
Animation can be one of the following values:
ID | Animation |
---|---|
0 | No animation |
1 | Swing arm |
2 | Damage animation |
3 | Leave bed |
5 | Eat food |
102 | (unknown) |
104 | Crouch |
105 | Uncrouch |
Only 1
(swing arm) and 3
(leave bed) is sent by notchian clients. Crouching is sent via 0x13. Damage is server-side, and so is not sent by notchian clients. See also 0x26.
Entity Action (0x13)
Client to Server only
Sent at least when crouching, leaving a bed, or sprinting. To send action animation to client use 0x28.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x13 | EID | int | 55534
|
Player ID |
Action ID | byte | 1
|
The ID of the action, see below. | |
Total Size: | 6 bytes |
Action ID can be one of the following values:
ID | Action |
---|---|
1 | Crouch |
2 | Uncrouch |
3 | Leave bed |
4 | Start sprinting |
5 | Stop sprinting |
Named Entity Spawn (0x14)
Server to Client only
The only named entities (at the moment) are players (either real or NPC/Bot). This packet is sent by the server when a player comes into visible range, not when a player joins.
Servers can, however, safely spawn player entities for players not in visible range. The client appears to handle it correctly.
The Notchian client is not okay with receiving player entity packets, including 0x14, that refer to its own username or EID; it will teleport to the absolute origin of the map and fall through the Void any time it receives them.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x14 | EID | int | 94453
|
Player ID |
Player Name | string16 | Twdtwd
|
Max length of 16 | |
X | int | 784
|
Player X as Absolute Integer | |
Y | int | 2131
|
Player Y as Absolute Integer | |
Z | int | -752
|
Player Z as Absolute Integer | |
Rotation | byte | 0
|
Player rotation as a packed byte | |
Pitch | byte | 0
|
Player rotation as a packed byte | |
Current Item | short | 0
|
The item the player is currently holding. Note that this should be 0 for "no item", unlike -1 used in other packets. A negative value crashes clients. | |
Total Size: | 23 bytes + length of strings |
Pickup Spawn (0x15)
A pickup spawn is sent by the server whenever an item on the ground (say a pickaxe thrown on the ground) comes into range of the player. (note: this means range for item vision, not range for pickup!) It used to be sent by the client when an item is dropped from a tile (chest or furnace) or from inventory, but that is now done with the new packets for server-side inventory (see 0x66).
It is completely acceptable for servers to ignore the EID issued by the client in this packet and instead create a new packet with a server-controlled EID when sending this packet out to clients.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x15 | EID | int | 157617
|
Unique entity ID |
Item | short | 4
|
The item ID | |
Count | byte | 1
|
The number of items | |
Damage/Data | short | New field in beta 1.2 update (see below) | ||
X | int | 133
|
Item X as Absolute Integer | |
Y | int | 913
|
Item Y as Absolute Integer | |
Z | int | 63552
|
Item Z as Absolute Integer | |
Rotation | byte | 252
|
Item rotation as a packed byte | |
Pitch | byte | 25
|
Item pitch as a packed byte | |
Roll | byte | 12
|
Item roll as a packed byte | |
Total Size: | 25 bytes |
"Damage" field This field is also used to store item metadata. E.g. you mined birch wood(its id is the same as normal wood) so you must set damage to the metadata of birch wood(2). The same case is wool. Id is the same but data is different.For example: you mined blue wool so your damage field should send value 0xB.
Collect Item (0x16)
Server to Client only
Sent by the server when someone picks up an item lying on the ground - its sole purpose appears to be the animation of the item flying towards you. It doesn't destroy the entity in the client memory (0x1D does that), and it doesn't add it to your inventory (0x67 does that). The server only checks for items to be picked up after each Player Position and Player Position & Look packet sent by the client.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x16 | Collected EID | int | 38
|
|
Collector EID | int | 20
|
||
Total Size: | 9 bytes |
Add Object/Vehicle (0x17)
Server to Client only
Sent by the server when an Object/Vehicle is created.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x17 | EID | int | 62
|
Entity ID of the Object |
Type | byte | 11
|
The type of object (see below) | |
X | int | 16080
|
The Absolute Integer X Position of the object | |
Y | int | 2299
|
The Absolute Integer Y Position of the object | |
Z | int | 592
|
The Absolute Integer Z Position of the object | |
Fireball thrower's entity ID | int | 0
|
It seems that if this is bigger than 0, this is a fireball and the next 3 fields are sent. | |
Unknown | short | 0
|
Seems to be used in calculation of the fireball's X | |
Unknown | short | 0
|
Seems to be used in calculation of the fireball's Y | |
Unknown | short | 0
|
Seems to be used in calculation of the fireball's Z | |
Total Size: | 22 or 28 bytes |
Object Types
Type ID | Type Name |
---|---|
1 | Boats |
10 | Minecart |
11 | Storage Cart |
12 | Powered Cart |
50 | Activated TNT |
60 | Arrow |
61 | Thrown Snowball |
62 | Thrown Egg |
70 | Falling Sand |
71 | Falling Gravel |
90 | Fishing Float |
Mob Spawn (0x18)
Server to Client only
Sent by the server when a Mob Entity is Spawned
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x18 | EID | int | 446
|
Entity ID |
Type | byte | 91
|
The type of mob. See Entities#Mobs | |
X | int | 13366
|
The Absolute Integer X Position of the object | |
Y | int | 2176
|
The Absolute Integer Y Position of the object | |
Z | int | 1680
|
The Absolute Integer Z Position of the object | |
Yaw | byte | -27
|
The X Axis rotation in steps of 2π/256 | |
Pitch | byte | 0
|
The Y Axis rotation in steps of 2π/256 | |
Metadata | Metadata | 127
|
Varies by mob, see Entities | |
Total Size: | 20 bytes + Metadata (at least 1) |
Entity: Painting (0x19)
This packet shows location, name, and type of painting.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x19 | Entity ID | int | 0x00000326
|
Unique entity ID |
Title | String16 | Creepers
|
Name of the painting; max length 13 (length of "SkullAndRoses") | |
X | int | 50
|
Center X coordinate | |
Y | int | 66
|
Center Y coordinate | |
Z | int | -50
|
Center Z coordinate | |
Direction | int | 0
|
Direction the painting faces (0 -z, 1 -x, 2 +z, 3 +x) |
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). E.g.
2x1 (1, 0) 4x4 (1, 2)
Experience Orb (0x1A)
Server to Client only
Spawns a one or more experience orbs. Co-ordinates are in absolute units.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x1A | Entity ID | int | 105668 | |
x | int | -1143 | ||
y | int | 1952 | ||
z | int | 1166 | ||
count | short | 7 | ||
Total Size: | 19 bytes |
Stance update (?) (0x1B)
This packet appears used in controlling position, orientation, and crouching. It doesn't seem to be used (see 0x0D).
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x1B | ??? | float | ||
??? | float | |||
??? | float | |||
??? | float | |||
??? | boolean | |||
??? | boolean |
Entity Velocity (0x1C)
This packet is new to version 4 of the protocol, and is believed to be Entity Velocity/Motion.
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).
(This packet data values are not fully verified)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x1C | Entity ID | int | 1805
|
The entity ID |
Velocity X | short | -1343
|
Velocity on the X axis | |
Velocity Y | short | 0
|
Velocity on the Y axis | |
Velocity Z | short | 0
|
Velocity on the Z axis | |
Total Size: | 11 bytes |
Destroy Entity (0x1D)
Server to Client only
Sent by the server when an Entity is to be destroyed on the client.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x1D | EID | int | 446
|
Entity ID |
Total Size: | 5 bytes |
Entity (0x1E)
Server to Client only
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 every game tick. So the meaning of this packet is basically that the entity did not move/look since the last such packet.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x1E | EID | int | 446
|
Entity ID |
Total Size: | 5 bytes |
Entity Relative Move (0x1F)
Server to Client only
This packet is sent by the server when an entity moves less then 4 blocks; if an entity moves more then 4 blocks Entity Teleport should be sent instead.
This packet allows at most four blocks movement in any direction, because byte range is from -128 to 127. Movement is an offset of Absolute Int; to convert relative move to block coordinate offset, divide by 32.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x1F | EID | int | 459
|
Entity ID |
dX | byte | 1
|
X axis Relative movement as an Absolute Integer | |
dY | byte | -7
|
Y axis Relative movement as an Absolute Integer | |
dZ | byte | 5
|
Z axis Relative movement as an Absolute Integer | |
Total Size: | 8 bytes |
Entity Look (0x20)
Server to Client only
This packet is sent by the server when an entity rotates. Example: "Yaw" field 64 means a 90 degree turn.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x20 | EID | int | 459
|
Entity ID |
Yaw | byte | 126
|
The X Axis rotation as a fraction of 360 | |
Pitch | byte | 0
|
The Y Axis rotation as a fraction of 360 | |
Total Size: | 7 bytes |
Entity Look and Relative Move (0x21)
Server to Client only
This packet is sent by the server when an entity rotates and moves. Since a byte range is limited from -128 to 127, and movement is offset of Absolute Int, this packet allows at most four blocks movement in any direction. (-128/32 == -4)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x21 | EID | int | 459
|
Entity ID |
dX | byte | 1
|
X axis Relative movement as an Absolute Integer | |
dY | byte | -7
|
Y axis Relative movement as an Absolute Integer | |
dZ | byte | 5
|
Z axis Relative movement as an Absolute Integer | |
Yaw | byte | 126
|
The X Axis rotation as a fraction of 360 | |
Pitch | byte | 0
|
The Y Axis rotation as a fraction of 360 | |
Total Size: | 10 bytes |
Entity Teleport (0x22)
Server to Client only
This packet is sent by the server when an entity moves more than 4 blocks.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x22 | EID | int | 459
|
Entity ID |
X | int | 14162
|
X axis position as an Absolute Integer | |
Y | int | 2176
|
Y axis position as an Absolute Integer | |
Z | int | 1111
|
Z axis position as an Absolute Integer | |
Yaw | byte | 126
|
The X Axis rotation as a fraction of 360 | |
Pitch | byte | 0
|
The Y Axis rotation as a fraction of 360 | |
Total Size: | 19 bytes |
Entity Status (0x26)
Server to Client only
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x26 | Entity ID | Int | 34353 | |
Entity Status | Byte | 0x03 | See below | |
Total Size: | 6 bytes |
Entity Status | Meaning |
---|---|
2 | Entity hurt |
3 | Entity dead |
6 | Wolf taming |
7 | Wolf tamed |
8 | Wolf shaking water off itself |
9 | (of self) Eating accepted by server |
Attach Entity (0x27)
This packet is new to version 4 of the protocol, and is believed to be Attach Entity.
This packet is sent when a player has been attached to an entity (e.g. Minecart)
(This packet data values are not fully verified)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x27 | Entity ID | int | 1298
|
The player entity ID being attached |
Vehicle ID | int | 1805
|
The vehicle entity ID attached to (-1 for unattaching) | |
Total Size: | 9 bytes |
Entity Metadata (0x28)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x28 | Entity ID | int | 0x00000326
|
Unique entity ID to update. |
Entity Metadata | Metadata | 0x00 0x01 0x7F
|
Metadata varies by entity. See Entities | |
Total Size: | 5 bytes + Metadata |
Entity Effect (0x29)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x29 | Entity ID | int | 14
|
Entity ID of a player |
Effect ID | byte | 17
|
See table below | |
Amplifier | byte | 0
|
||
Duration | short | 64
|
||
Total Size: | 9 bytes |
Effects
Only noted effects are currently implemented by the 1.8pre2 client/server
ID | Meaning | Client implementation | Server implementation |
---|---|---|---|
1 | moveSpeed | Increases player speed and FOV. | |
2 | moveSlowdown | Decreases player speed and FOV. | |
3 | digSpeed | Increases player dig speed | |
4 | digSlowDown | Decreases player dig speed | |
5 | damageBoost | ||
6 | heal | ||
7 | harm | ||
8 | jump | ||
9 | confusion | Portal-like effect | |
10 | regeneration | Hearts pulse one-by-one | Caused by golden apple. Health regenerates over 600-tick (30s) period. |
11 | resistance | ||
12 | fireResistance | ||
13 | waterBreathing | Bubbles do not decrease underwater | |
14 | invisibility | ||
15 | blindness | ||
16 | nightVision | ||
17 | hunger | Food bar turns green | Caused by poisoning from Rotten Flesh or Raw Chicken |
18 | weakness | ||
19 | poison | Hearts turn yellow | Caused by poisoning from cave (blue) spider |
Remove Entity Effect (0x2A)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x2a | Entity ID | int | Entity ID of a player | |
Effect ID | byte | 17
|
See table above | |
Total Size: | 6 bytes |
Experience (0x2B)
Sent by the server when the client should change experience levels.
The amount of experience needed to reach the next level increases by 10 with each level. At level 0, you need 10 experience to progress to level 1. At level 1, the requirement is 20 to progress, and so forth.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x2B | Current experience | byte | 15
|
Experience at current level |
Level | byte | 2
|
||
Total experience | short | 45
|
||
Total Size: | 5 bytes |
Pre-Chunk (0x32)
Server to Client only
This packet is sent by the server to notify the client to initialize (Mode=1) or unload (Mode=0) a chunk. The client is expected to allocate space for a full chunk (currently 16 x 128 x 16 blocks). One or more 0x33 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.
When sending initial terrain to spawn the player, make sure all pre-chunks are sent before all chunks.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x32 | X | int | -9
|
Chunk X Coordinate |
Z | int | 12
|
Chunk Z Coordinate | |
Mode | bool | 1
|
If mode is 0 the client will unload the chunk, otherwise the client will initialize the chunk | |
Total Size: | 10 bytes |
Map Chunk (0x33)
Server to Client only
The client will overwrite all or part of a chunk using the region of data contained in this packet. The server specifies the region to write using a block position and size in X,Y,Z. Note that this region will always be inside a single chunk. (At least using the vanilla server. Unknown if the client has this limitation.)
When a client doesn't have a chunk loaded, the server will send a 0x32 packet first (with mode=true) to tell the client to initialize the chunk, followed by a 0x33 packet containing all of the chunk data. 0x32 packet is not sent by the server when updating a chunk that the client already has loaded.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x33 | X | int | 128
|
Block X Coordinate |
Y | short | 0
|
Block Y Coordinate | |
Z | int | -192
|
Block Z Coordinate | |
Size_X | byte | 15
|
Size_X is Actual X Size -1 | |
Size_Y | byte | 127
|
Size_Y is Actual Y Size -1 | |
Size_Z | byte | 15
|
Size_Z is Actual Z Size -1 | |
Compressed size | int | 3663
|
Size of compressed region data | |
Compressed data | byte array | …
|
The region data is compressed using ZLib Deflate function. | |
Total Size: | 18 bytes + Compressed chunk size |
X, Y, Z
This is the start position of the region, in world block coordinates.
To find which chunk is affected, in the same coordinates given by packet 0x32:
ChunkX = X >> 4 ChunkY = Y >> 7 ChunkZ = Z >> 4
And conversely, which local block in the chunk to start at:
StartX = X & 15 StartY = Y & 127 (not always 0!) StartZ = Z & 15
SizeX, SizeY, SizeZ
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 maximum size of a byte is 255; 256 - 1 = 255).
Compressed data
The data is compressed using the deflate() function in zlib. After uncompressing, the data consists of four sequential sections, in order:
- Block type 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 (Size_X+1) * (Size_Y+1) * (Size_Z+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 Size_X number of x planes, each plane made up of Size_Z number of z rows, each row made up of Size_Y blocks indexed by y coordinate in order.
The block type array is indexed with:
index = y + (z * (Size_Y+1)) + (x * (Size_Y+1) * (Size_Z+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 second nibble.
If you have a FULL map chunk (Size_X = 15, Size_Y = 127, Size_Z = 15, you can calculate index coordinates:
x = X + ( index >> 11 ) y = index & 0x7F z = Z + ( (index & 0x780) >> 7 )
Multi Block Change (0x34)
Further investigation shows that 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 short into coordinates (top 4 bits is X, next 4 bits is Z, bottom 8 bits is Y), you get things like [((8, 7, 4), 11, 0), ((7, 13, 6), 11, 0), ((13, 1, 8), 11, 0), ((7, 6, 6), 11, 0)].
See the Block Change command for description of the general format of a block change.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x34 | Chunk X | int | -9
|
Chunk X Coordinate |
Chunk Z | int | 12
|
Chunk Z Coordinate | |
Array size | short | 2
|
The total number of elements per array | |
Coordinate array | short array | …
|
The coordinates of the blocks to change | |
Type array | byte array | …
|
The type for each block change | |
Metadata array | byte array | …
|
The Metadata for each block changed | |
Total Size: | 11 bytes + Arrays |
Block Change (0x35)
Block metadata varies by block type - it should be
0x00
for most blocks with a few exceptions, shown in the table below.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x35 | X | int | 502
|
Block X Coordinate |
Y | byte | 71
|
Block Y Coordinate | |
Z | int | 18
|
Block Z Coordinate | |
Block Type | byte | 78
|
The new block type for the block | |
Block Metadata | byte | 0
|
The new Metadata for the block | |
Total Size: | 12 bytes |
Block Action (0x36)
Server to Client only
This packet is used for a number of things:
- Chests opening and closing
- Pistons pushing and pulling
- Note blocks playing
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x35 | X | int | 502
|
Block X Coordinate |
Y | short | 71
|
Block Y Coordinate | |
Z | int | 18
|
Block Z Coordinate | |
Byte 1 | byte | 3
|
Varies depending on block - see below | |
Byte 2 | byte | 17
|
Varies depending on block - see below | |
Total Size: | 13 bytes |
Note Block
It shows the note particle being emitted from the block as well as playing the tone.
Byte 1
Instrument type.
Type ID | Type Name |
---|---|
0 | Harp |
1 | Double Bass |
2 | Snare Drum |
3 | Clicks/Sticks |
4 | Bass Drum |
Byte 2
The pitch of the note (between 0-24 inclusive where 0 is the lowest and 24 is the highest). More information about how the pitch values correspond to notes in real life are available on the official Minecraft wiki.
Piston
Byte 1
The state the piston changes to - 0 for pushing, 1 for pulling.
Byte 2
Direction.
Direction ID | Direction |
---|---|
0 | Down |
1 | Up |
2 | South |
3 | West |
4 | North |
5 | East |
Chest
Animates the chest's lid opening. Note that the notchian server will send this every 3s even if the state hasn't changed.
Byte 1
Not used - always 1
Byte 2
State of the chest - 0 for closed, 1 for open.
Explosion (0x3C)
This command is not fully understood.
Seems to be sent when an explosion occurs (both creepers and TNT).
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x3C | X | double | ||
Y | double | |||
Z | double | |||
Unknown | float | 3.0 | radius? | |
Record count | int | This is the count, not the size. The size is 3 times this value. | ||
Records | (byte, byte, byte) × count | Each record is 3 bytes, which seem to be XYZ offsets of affected blocks. | ||
Total Size: | 33 bytes + 3*(Record count) bytes |
Sound effect (0x3D)
Sent when a client is to play a sound effect.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x3D | Effect ID | int | 1003 | The ID of the sound effect to play, see below. |
X | int | The X location of the effect. | ||
Y | byte | The Y location of the effect. | ||
Z | int | The Z location of the effect. | ||
Sound data | int | 0 | Extra data about RECORD_PLAY, SMOKE, and BLOCK_BREAK | |
Total Size: | 18 bytes |
Valid sound effects are:
Effect ID | Name | Notes |
---|---|---|
1000 | CLICK2 | |
1001 | CLICK1 | |
1002 | BOW_FIRE | |
1003 | DOOR_TOGGLE | |
1004 | EXTINGUISH | |
1005 | RECORD_PLAY | Has data (presumably record ID) |
2000 | SMOKE | Has data (direction, check below) |
2001 | BLOCK_BREAK | Has data (Block ID broken) |
Smoke is a silent effect with only a visual element.
Smoke Directions
Direction ID | Direction |
---|---|
0 | South - East |
1 | South |
2 | South - West |
3 | East |
4 | (Up or middle ?) |
5 | West |
6 | North - East |
7 | North |
8 | North - West |
New/Invalid State (0x46)
This packet appeared with protocol version 10. Currently, it appears when a bed can't be used as a spawn point and when the rain state changes. it could have additional uses in the future.
The class has an array of strings linked to reason codes 0, 1, 2, and 3 but only the codes for 1 and 2 are null.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x46 | Reason | byte | 0 | |
Game mode | byte | 0 | Used only when reason = 3. 0 is survival, 1 is creative. | |
Total Size: | 3 bytes |
Reason codes
Code | Effect | Text |
---|---|---|
0 | Invalid Bed | "tile.bed.notValid" |
1 | Begin raining | null |
2 | End raining | null |
3 | Change game mode | gameMode.changed |
Thunderbolt (0x47)
Server to Client only
With this packet, the server notifies the client of thunderbolts striking somewhere (near the player?). The coordinates specify where exactly the thunderbolt strikes.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x47 | Entity ID | int | 4 | The entity ID of the thunderbolt |
Unknown | boolean | true | Always true. Might have a meaning in the future... | |
X | int | 133 | Thunderbolt X as Absolute Integer | |
Y | int | 913 | Thunderbolt Y as Absolute Integer | |
Z | int | 63552 | Thunderbolt Z as Absolute Integer | |
Total Size: | 18 bytes |
Open window (0x64)
This is sent to the client when it should open an inventory, such as a chest, workbench, or furnace. This message is not sent anywhere for clients opening their own inventory.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x64 | Window id | byte | 123 | A unique id number for the window to be displayed. Notchian server implementation is a counter, starting at 1. |
Inventory Type | byte | 2 | The window type to use for display. Check below | |
Window title | string16 | Chest
|
The title of the window. | |
Number of Slots | byte | 3 | Number of slots in the window (excluding the number of slots in the player inventory). | |
Total Size: | 6 bytes + length of string |
The window titles sent by the Notchian server are "Chest", "Large chest", "Crafting", "Furnace", and "Trap". Notchian clients force window titles for some windows, like dispensers and furnaces, but other titles are customizable. However, the window title sent by the server is always used for chests. See inventory windows for further information.
Close window (0x65)
This packet is sent by the client when closing a window. This packet is sent from the server to the client when a window is forcibly closed, such as when a chest is destroyed while it's open.
Note, notchian clients send a close window message with window id 0 to close their inventory even though there is never an Open Window message for inventory.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x65 | Window id | byte | 0 | This is the id of the window that was closed. 0 for inventory. |
Total Size: | 2 bytes |
Window click (0x66)
Client to Server only
This command is not fully understood.
This packet is sent by the player when it clicks on a slot in a window.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x66 | Window id | byte | 0
|
The id of the window which was clicked. 0 for player inventory. |
Slot | short | 36
|
The clicked slot. See below. | |
Right-click | byte | 1
|
1 when right-clicking and otherwise 0. | |
Action number | short | 12
|
A unique number for the action, used for transaction handling (See the Transaction packet). | |
Shift | bool | 0
|
This is true if the user was holding keyboard shift when they clicked. | |
Item ID | short | 3
|
ID of Item that was in the slot or -1 if no item. If -1, this is the last field in the packet. | |
Item count | byte | 64
|
Number of items that were in the slot | |
Item uses | short | 10
|
Number of times the item was used that was in the slot | |
Total Size: | 10 bytes (+3 for item ID != -1) |
See inventory windows for further information about how slots are indexed.
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.
The Item (short, optional byte,short) is a critical piece of information in this packet. The Item that is sent by the client is what is in the slot before it is clicked. The server compares that with it's notes, and accepts the transaction if items match. Note that the client seems to send valid item IDs (rather than -1) even when Item count == 0.
Set slot (0x67)
Server to Client only
This command is not fully understood.
Sent by the server when an item in a slot (in a window) is added/removed.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x67 | Window id | byte | 0
|
The window which is being updated. 0 for player inventory. Note that all known window types include the player inventory. This packet will only be sent for the currently opened window while the player is performing actions, even if it affects the player inventory. After the window is closed, a number of these packets are sent to update the player's inventory window (0). |
Slot | short | 36
|
The slot that should be updated | |
Item ID | short | -1
|
When -1, this is the last value in this packet. -1 means no item. | |
Item Count | byte | 64
|
Number of items in a stack. Not sent when Item ID is -1. | |
Item uses | short | 3
|
Not sent when Item ID is -1. | |
Total Size: | 6 bytes (+3 for item ID != -1) |
Note that if window ID and slot are both -1, it means the item currently attached to the cursor.
See inventory windows for further information about how slots are indexed.
Slots: [1]
Window items (0x68)
Server to Client only
Sent by the server when an item in a slot (in a window) is added/removed. This includes the main inventory, equipped armour and crafting slots.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x68 | Window id | byte | 1
|
The id of window which items are being sent for. 0 for player inventory. |
Count | short | 4
|
The number of slots (see below) | |
Payload | … |
|
The payload (see below) | |
Total Size: | 4 bytes + size of payload |
See inventory windows for further information about how slots are indexed.
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 slots. Each slot consists of a short (item ID) optionally followed by a byte-short pair (count and uses) as long as the item ID does not equal -1
, which signifies an empty slot.
Uses is the number of times an item has been used (the value starts at 0 and counts up.) Note that an invalid use of an item may count as 2 uses.
This pseudocode assumes you have already read all the fields except payload from the socket. It also assumes that buffer
is mutable - i.e. reading a value from the start of buffer
also removes that data from the buffer.
for i in slot_count:
item_id = read short from buffer
if item_id is not equal to -1:
count = read byte from buffer
uses = read short from buffer
inventory[slot] = new item(item_id, count, uses)
else:
inventory[slot] = None
And an example with a non-mutable buffer:
j = 0
for i in slot_count:
item_id = read buffer[j] as short
if item_id is not equal to -1:
count = read buffer[j+1] as byte
uses = read buffer[j+2] as short
inventory[slot] = new item(item_id, count, uses)
j = j + 2
else:
inventory[slot] = None
j = j + 1
Update progress bar (0x69)
Server to Client only
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x69 | Window id | byte | 2 | The id of the window that the progress bar is in. |
Progress bar | short | 1 | Which of the progress bars that should be updated. (For furnaces, 0 = progress arrow, 1 = fire icon) | |
Value | short | 650 | The value of the progress bar. The maximum values vary depending on the progress bar. Presumably the values are specified as in-game ticks. Some progress bar values increase, while others decrease. For furnaces, 0 is empty, full progress arrow = about 180, full fire icon = about 250) | |
Total Size: | 6 bytes |
Transaction (0x6A)
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 packet.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x6A | Window id | byte | 0 | The id of the window that the action occurred in. |
Action number | short | 12 | Every action that is to be accepted has a unique number. This field corresponds to that number. | |
Accepted? | boolean | true | Whether the action was accepted. | |
Total Size: | 5 bytes |
Creative inventory action (0x6B)
While the user is in the standard inventory (i.e., not a crafting bench) on a creative-mode server then the server will send this packet:
- If an item is dropped into the quick bar
- If an item is picked up from the quick bar (special case: item id is -1 and quantity/damage are both 0)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x6B | Slot | short | 36 | Inventory slot |
Item id | short | 35 | Item ID being placed (or -1) | |
Quantity | short | 1 | ||
Damage | short | 9 | Note: also used for block metadata (as with many packets) | |
Total Size: | 9 bytes |
Update Sign (0x82)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x82 | X | int | 128 | Block X Coordinate |
Y | short | 0 | Block Y Coordinate | |
Z | int | -128 | Block Z Coordinate | |
Text1 | string16 | First line
|
First line of text in the sign | |
Text2 | string16 | Second line
|
Second line of text in the sign | |
Text3 | string16 | Third line
|
Third line of text in the sign | |
Text4 | string16 | Fourth line
|
Fourth line of text in the sign | |
Total Size: | 11 bytes + 4 strings |
This message is sent from the server to the client whenever a sign is discovered or created. This message is sent from the client to the server when the "Done" button is pushed after placing a sign. This message is NOT sent when a sign is destroyed or unloaded.
Item Data (0x83)
Server to Client only
Sent to specify complex data on an item; currently used only for maps.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0x83 | Item Type | short | 358
|
Type of item being modified |
Item ID | short | 0
|
The ID (damage value) of the item being modified | |
Text length | unsigned byte | 35
|
Length of following byte array | |
Text | byte array | {0,0,0,20,20,20,20,20} | ASCII text. | |
Total Size: | 6 bytes + Text length |
Maps If the first byte of the text is 0, the next two bytes are X start and Y start and the rest of the bytes are the colors in that column.
If the first byte of the text is 1, the rest of the bytes are in groups of three: (data, x, y). The lower half of the data is the type (always 0 under vanilla) and the upper half is the direction.
Increment Statistic (0xC8)
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0xC8 | Statistic ID | int | 1003 | The ID of the statistic. See List of statistics. |
Amount | byte | 1 | The amount to increment the statistic. | |
Total Size: | 6 bytes |
Player List Item (0xC9)
Sent by the notchian server to update the user list (<tab> in the client). The server sends one packet per user per tick, amounting to 20 packets/s for 1 online user, 40 for 2, and so forth.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0xC9 | Player name | string16 | barneygale | Supports chat colouring, limited to 16 characters. |
Online | bool | true | If false, the client will remove the user from the list. | |
Ping | short | 193 | Ping, presumably in ms. | |
Total Size: | 6 bytes + length of string |
Server List Ping (0xFE)
To load server info in the multiplayer menu, the notchian client connects to each known server and sends an 0xFE.
In return, the server sends a kick (0xFF), with its string containing data (server description, number of users, number of slots), delimited by a §.
Note that as this is the last packet you'll see, you can get away with just chopping off the first three bytes (the ident and the string length) and decoding the remainder as a UCS-2 string.
If the number of available slots sent is equal to or less than 0, the client should display it as "???".
Example server pinger:
https://gist.github.com/1209061 (Python)
https://gist.github.com/1235274 (PHP)
Packet ID |
---|
0xFE |
Disconnect/Kick (0xFF)
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.
Packet ID | Field Name | Field Type | Example | Notes |
---|---|---|---|---|
0xFF | Reason | string16 | The server is full!
|
Displayed to the client when the connection terminates |
Total Size: | 3 bytes + length of strings |
Protocol History
Provided below is a changelog of the server protocol starting on 2010-08-20. The wiki history feature may also be used to investigate changes.
The current development branch is chronicled at "Pre-release protocol"
2011-9-14
- Beta 1.8 release.
- Protocol version is now 17
2011-9-13
- Beta 1.8 pre2-release.
- Protocol version is now 16
- Packet 0x01 (Login) changed (added byte, world height now unsigned)
- Packet 0x09 (Respawn) changed (added byte)
- Packet 0x64 (Open Window) changed (Window title changed from string8 to string16)
- New packet 0x1a (Experience Orb) added
- Assumedly 0x17 (Add Object/Vehicle) is no longer used for exp orbs.
2011-9-10
- Beta 1.8 pre-release.
- Protocol version is now 15
- Packet 0x00 (Keep Alive) changed (added keep-alive id)
- Packet 0x01 (Login) changed (added server mode, height limit, and an unknown field)
- Packet 0x08 (Health) changed (added food bar and food saturation)
- Packet 0x09 (Respawn) changed (added map seed, server mode, height limit)
- Packet 0x13 (Entity Action) has new values for starting/stopping sprinting.
- Packet 0x46 (New/invalid state) changed (added game mode reason, and a game mode byte)
- New packet 0x29 (Entity Effect) added
- New packet 0x2a (Remove Entity Effect) added
- New packet 0x2b (Experience update) added
- New packet 0x6b (Creative item get) added
- New packet 0xc9 (Player list item) added
- New packet 0xfe (Server list ping) added
- New values for 0x13 (Entity Action): start sprinting, stop sprinting
- New value for 0x17 (Add Object/Vehicle): experience orb
2011-6-30
- Beta 1.7 released.
- Protocol version number is now 14
- No new packets
- Packet 0x36 (Block Action) is now used for pistons too.
2011-5-26
- Beta 1.6 released.
- Protocol increase by 2: 13
- Packet 0x09 (Respawn) changed (added world byte)
- Packet 0x17 (Add Object) changed.
- Packet 0x3d (Sound effect) added
- Packet 0x83 (Map Data) added
2011-4-19
- Beta 1.5 released.
- Some packet info at https://gist.github.com/929803
- Packet 0x01 (Login Request) changed (removed second string)
- Packet 0x66 (Window Click) changed (added bool for shift)
- Added two new packets: 0x47 (Thunderbolt) and 0xC8 (Increment Statistic) (classes eq and nj, respectively)
- Protocol version number is now 11
- All of the strings are now UCS-2, except for Open window (0x64), which is still UTF-8
2011-3-31
- Beta 1.4 released.
- New packet 0x46.
- Protocol version number is now 10
- TODO: The protocol itself does not seem to have changed much, but what about possible data values and stuff like that?
2011-2-22
- Beta 1.3 released.
- New packets 0x11, 0x1B: Some information at https://gist.github.com/841590
- Protocol number is now 9 (updated)
2011-1-13
- Beta 1.2 released.
- More packet changes (pastebin): 0x05, 0x0F, 0x13, 0x15, 0x18, 0x19, 0x28, 0x36, 0x66, 0x67.
2010-12-20
- Notch released Beta on time! Amazing! Refactored the page to be slightly smaller and easier to navigate.
- A whole host of packet changes. 0x05, 0x08, 0x10, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, and 0x82. Packets 0x11 and 0x3b removed.
2010-12-01
- Protocol version changed to 6
- Packet 0x12 (Animation) got a lot more new values
- Packet 0x26 changed, now indicates entity damage, death and explosion (for creepers, TNT not tested)
- Packet 0x3B now being sent from client
- Packet 0x3C added
- (need info on other changes)
2010-11-24
- Protocol version changed to 5
- Packet 0x07 (Use Entity) got a new field (byte)
- Packet 0x08 (Update Health) added
- Packet 0x09 (Respawn) added
- Packet 0x12 (Animation) started getting non-boolean values for the Animation field
- Packet 0x26 (Entity Death) added
2010-11-10
- Protocol version changed to 4
- Packet 0x01 (login request) changed
- Packet 0x07 (Use Entity?) added
- Packet 0x1C (Entity Velocity?) added
- Packet 0x27 (Attach Entity?) added
2010-10-31
- Protocol version changed to 3
- Packet 0x01 (login request) changed
2010-09-10
- Protocol version changed to 2
- Packets 0x05, 0x06, 0x3B added
- Server-side inventory (no verification)
- Vanilla adds experimental monsters (only damaged by fire)
2010-08-20
- Protocol version reset from 14 to 1
- Packet 0x04 (time update) added