Classic Protocol Extension
Classic Protocol Extension (CPE) is a project to augment the Minecraft Classic network protocol with new and improved functionality.
Extensions are designed to keep extended clients and servers compatible with standard clients and servers. Standard clients and extended clients can play on the same server side-by-side. Extensions are designed to be modular: custom clients and servers can selectively implement any subset of extensions, and only mutually-supported extensions will be used.
This specification has not yet been finalized, and is subject to change.
Last revision: 6 April 2014. See the history subpage for a chronology of changes. |
Contents
Support
- See support subpage for a detailed table.
Custom servers that already support CPE: FemtoCraft, D3, LegendCraft, GemsCraft
Custom servers that plan to add support: 800Craft, cloudBox, fCraft, GGS
Custom clients that already support CPE: ClassiCube Client
Custom clients that plan to add support: Charged Miners
Negotiation
When CPE-capable client connects to a CPE-capable server, a brief negotiation needs to happen before any extensions are used. Client and server declare their capabilities and determine which extensions are mutually supported. All CPE-capable software is required to support this.
Client behavior: Extended clients must use magic number of 0x42
(66
decimal) for the padding byte of the ClientIdentification packet. It must then await a response. If server responds with any packet other than ExtInfo, client must assume that the server does NOT support CPE. If the server responds with an ExtInfo packet, client must parse it and any ExtEntry packets that follow. Client must then compare its locally-supported set of extensions with the list of extensions provided by the server, and find an intersection of these sets. These are the mutually-supported extensions. Client must now send ExtInfo packet of its own, followed by a list of zero or more client-supported extensions. After sending the last of ExtEntry packets, client should activate all mutually-supported extensions and resume normal login procedure.
Server behavior: When a client connects, server must read the ClientIdentification packet and check its padding byte. If this byte is set to 0x42
(66
decimal), assume that the client supports CPE. If this byte is set to any other value, assume that the client does NOT support CPE.
Server must immediately reply to CPE clients with an ExtInfo packet, followed by zero or more ExtEntry packets, and await a response from the client. Client will respond with one ExtInfo and zero or more ExtEntry packets. Server must then compare its locally-supported set of extensions with the list of extensions provided by the client, and find an intersection of these sets. These are the mutually-supported extensions. After receiving the last of ExtEntry packets, server should activate all mutually-supported extensions and resume normal login procedure.
Note 1: All standard/non-extended clients use 0x00
for the padding byte. All standard servers ignore this padding byte. Therefore, this negotiation process does not affect compatibility with standard software.
Note 2: Do not make any assumptions about supported functionality based on the AppName field of ExtInfo packet. It's for logging purposes only.
Note 3: Do not declare support for an extension until it is FULLY implemented, except for debugging.
ExtInfo Packet
Packet ID Field Name Field Type Example Notes 0x10 (16)
AppName string MyServer
Client or server software name ExtensionCount short 1 Between 0 and 32767 Total Size: 67 bytes
ExtEntry Packet
Packet ID Field Name Field Type Example Notes 0x11 (17)
ExtName string MyExtension
Name of a supported extension Version int 1 Only extensions with identical version numbers should be considered compatible. Total Size: 69 bytes
Extensions
Note: The section heading is the name of the extension. Packet names are not same as extension names. For example, the first extension listed here is named "ClickDistance" and not "SetClickDistance".
Do you have an idea for an extension? Please post it on the Proposals subpage. |
ClickDistance
- Used to extend or restrict the distance at which client may click blocks, controlled by the server. Click range is given in player-space units (32 units per block). In Minecraft Classic, the default range is 160.
- Motivation: This extension allows trusted players to have a wider or virtually-unlimited reach. It may simplify operation of certain bots. Restricting the reach may allow new games/mini-games.
- Client Behavior: Upon receiving a SetClickDistance packet, client should immediately apply the change. Distance should persist between worlds/maps.
- Server Behavior: Server should send SetClickDistance packet when the server connects, or whenever their permitted click distance changes. Server should allow for some margin-of-error (+/- 1 block) when enforcing click distance restrictions.
SetClickDistance packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x12 (18)
Distance short 160 Total Size: 3 bytes
CustomBlocks
- Used to add support for custom block types. Custom block IDs start at 50 (0x32). New block types will be added in batches, a few at a time. Both client and server declare which batch they support, and use the lower of the two versions. Claiming to supporting a batch implies fully implementing all the batches that came before it. If either server or client do not support this extension, only the standard 50 block types should be used.
- Motivation: Adding new visually distinct blocks, to enhance Classic players' experience.
- Client behavior: Client must expect a CustomBlockSupportLevel packet from a compatible server immediately after sending the last ExtEntry packet. It should then reply with its own CustomBlockSupportLevel packet, containing its actual support level. Client must then use the lower of the two levels in operation. Client must not send any block types that are not defined by the current support level. Client should expect ServerIdentification packet only AFTER sending its CustomBlockSupportLevel packet.
- Server behavior: Server must send a CustomBlockSupportLevel packet to compatible clients immediately after receiving the last ExtEntry packet from the client. It should then wait to receive a CustomBlockSupportLevel packet from the client before sending the ServerIdentification packet. Server must then use the lower of the two levels in operation. If this level is lower than the server's, it has to filter data sent to the client, to make sure that the client never receives any block types that it does not support. Each level will define what substitutions to use.
CustomBlockSupportLevel packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x13 (19)
SupportLevel byte 1 Total Size: 2
Blocks in support level 1
- Client must be able to receive/render all 16 custom blocks to claim support. Server must be able to receive/store all 16 custom blocks to claim support.
Block name Block ID Fallback name Fallback ID CobblestoneSlab 0x32 (50) Slab 0x2C (44) Rope 0x33 (51) BrownMushroom 0x27 (39) Sandstone 0x34 (52) Sand 0x0C (12) Snow 0x35 (53) Air 0x00 (0) Fire 0x36 (54) Lava 0x0A (10) LightPinkWool 0x37 (55) Pink 0x21 (33) ForestGreenWool 0x38 (56) Green 0x19 (25) BrownWool 0x39 (57) Dirt 0x03 (3) DeepBlue 0x3A (58) Blue 0x1d (29) Turquoise 0x3B (59) Cyan 0x1c (28) Ice 0x3C (60) Glass 0x14 (20) CeramicTile 0x3D (61) Iron 0x2a (42) Magma 0x3E (62) Obsidian 0x31 (49) Pillar 0x3F (63) White 0x24 (36) Crate 0x40 (64) WoodenPlanks 0x05 (5) StoneBrick 0x41 (65) Stone 0x01 (1)
- Block IDs for future support levels are guaranteed to be assigned monotonically, incrementally, and permanently.
HeldBlock
- Provides a way for the client to notify the server about the blocktype that it is currently holding, and for the server to change the currently-held block type.
- Motivation: This allows server to know which block player is holding, for example for drawing commands, without needing to wait for the player's click. it also allows for features like /Spectate to show what block a spectated player is holding.
- Client behavior: When this extension is mutually supported, client should use the PlayerID field of the PositionAndOrientation packet (currently unused) to indicate which blocktype the client is currently holding. It should be ready to accept HoldThis packets to change the block that the player is holding. If
0
is given for BlockToHold, client should hide the hand/block from the screen, and should not be able to click blocks, until they switch to a different blocktype. If an unrecognized blocktype is given, no action is needed. - Server behavior: The server can use HoldThis packet to force the client to hold the desired block type. It should be done sparingly.
HoldThis packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x14 (20)
BlockToHold byte 49
Standard block type PreventChange byte 0 0 = Allow player to change blocktype 1 = Prevent player from changing blocktype
Total Size: 3 bytes
EmoteFix
- This extension indicates that the client can render emotes (ASCII control characters) in chat properly, without padding or suffixes that are required for vanilla client. This extension does not define any new packets.
- Motivation: To improve appearance of emotes in chat.
- Client behavior: Client should not emulate vanilla client's quirks.
- Server behavior: Server should not pad or suffix emotes in chat.
TextHotKey
- This extension allows the server to define "hotkeys" for certain commands.
- Motivation: To speed up and simplify access to commonly-used commands and command macros by providing server-defined client-side hotkeys.
- Client behavior: Client should not try to persist previously-defined hotkeys between sessions. When a defined hotkey is activated by the user, client should open up a text prompt and type in contents of the Action field. A newline character (
\n
) in the Action field indicates that whatever is currently typed-in should be sent to the server. If Action does not end with a newline, text prompt should be left open, for the user to complete. Client may provide a way for the user to see a list of currently-defined hotkeys, and a way to notify the user when a hotkey was activated. - Server behavior: The server should send a definition of each hotkey (SetTextHotKey packet) once per connection.
SetTextHotKey packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x15 (21)
Label string Copy
Readable name of the hotkey Action string /Copy
Text to type in KeyCode int 113
LWJGL keycode of the key KeyMods byte 0
Key modifier flags, may be combined: - 0 = None
- 1 = Ctrl
- 2 = Shift
- 4 = Alt
Total Size: 134 bytes
ExtPlayerList
- Motivation: Provides more flexibility in naming of players and loading of skins, autocompletion, and player tab-list display. Separates tracking of in-game entities (spawned player models) and names on the player list. ExtAddPlayerName/ExtRemovePlayerName packets take over managing the player names list (tab-list), and ExtAddEntity/DespawnPlayer packets are used only to manage in-game entities.
Client Behavior
- When ExtAddPlayerName packet is received for an unrecognized NameID, a new entry must be added to the autocompletion list and tab-list. When receiving ExtAddPlayerName packet for an already-listed NameID, client must update its ListName, GroupName, and GroupRank. Name list must persist when client changes worlds/maps.
- Names on the tab-list should be grouped by GroupName in the player tab-list. Names within a GroupName should be sorted by GroupRank (in ascending order). Names with the same GroupName and GroupRank should be sorted alphabetically by ListName.
- When an ExtAddEntity packet is received, it must be treated as the SpawnPlayer packet. InGameName should be shown above the player's heads in-game. Skin should be loaded using the given SkinName for a player name. When client receives ExtAddEntity packet for an already-spawned player, a duplicate entity must not be spawned and existing entity's position should not be changed. Instead their InGameName and SkinName should be updated. If a negative ID is given for ExtAddEntity, client must update player's own spawn point, InGameName, and SkinName. The client must ignore regular SpawnPlayer packets, if any are received. Name list should not be affected by ExtAddEntity.
- Color codes may be either drawn or stripped from ListName, GroupName, and InGameName.
- When a standard DespawnPlayer packet is received for a recognized EntityID, player model should be removed from a world. Name list should not be affected by DespawnPlayer.
- When ExtRemovePlayerName packet is received for a recognized NameID, they should be removed from autocompletion list and tab-list. When DespawnPlayer or ExtRemovePlayerName packet is received for a negative or unrecognized PlayerID, no action should be taken.
Server Behavior
- When a new player connects to the server, ExtAddPlayerName must be sent. GroupName and GroupRank can be used in any way, for example to group players by map/world or rank/class/faction. Server must use ExtAddEntity in place of standard SpawnPlayer packet. Server should re-send ExtAddPlayerName packet, using the identical PlayerID, when player's ListName, GroupName, or GroupRank change. Server must reliably send an ExtRemovePlayerName when the player disconnects. Color codes are permitted in ListName, GroupName, and InGameName.
ExtAddPlayerName Packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x16 (22)
NameID short 5
Between 0 and 255 PlayerName string Notch
Player name used for autocompletion. May be left empty (exclude from autocompletion).
ListName string &c[Op]Notch
Name displayed in the in-game list. GroupName string Staff
GroupRank byte 0
Rank of a player within the group. A lower number means higher rank.
Total Size: 196 bytes
ExtAddEntity Packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x17 (23)
EntityID byte 5
Between 0 and 127 InGameName string &cNotch
Player name to be shown in-game, hovering above player model. SkinName string Notch
Player name whose skin should be used by the client. Total Size: 130 bytes
ExtRemovePlayerName Packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x18 (24)
NameID short 5
Between 0 and 255 Matches NameID of the ExtAddPlayerName packet
Total Size: 3 bytes
EnvColors
- This extension allows server to alter some of the colors used by the client in environment rendering.
- Motivation: To allow the server to give worlds/maps a unique feel: time-of-day, weather/climate, lighting effect, etc.
- Client behavior: Client must check for EnvSetColor packets right before LevelFinalize packet, and apply these changes before the map is displayed. Client must be able to read this packet at other times, but it is not required to then apply the changes immediately. If an unrecognized or unsupported Variable field is given, no action is needed. If an out-of-range color is given by the server (i.e. if any of Red, Green, or Blue is less than
0
or greater than255
), then the specified Variable should be reset to its default value. - Server behavior: Server should normally only use EnvSetColor packets right before the LevelFinalize packet. To reset a variable to its default value, the server should send a packet with value
-1
for Red, Green, and Blue.
EnvSetColor Packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x19 (25)
Variable byte 1
Enumeration of environmental variables - 0 = sky color
- 1 = cloud color
- 2 = fog color
- 3 = ambient light (blocks in shadow) color
- 4 = diffuse light (sunlight) color
Red short 25
Between 0 and 255 Green short 128
Between 0 and 255 Blue short 0
Between 0 and 255 Total Size: 8 bytes
SelectionCuboid
- Motivation: Allows the server to highlight parts of a world. Applications include zoning, previewing draw commands, previewing undo commands.
- Coordinates: {StartX,StartY,StartZ} are coordinates of the block inside the selection that is closest to the map origin. {EndX,EndY,EndZ} are coordinates of the block inside the selection that is furthest from the map origin. Therefore, the resulting selection has dimensions {EndX-StartX+1, EndY-StartY+1, EndZ-StartZ+1).
- Client behavior: Client should be ready to receive MakeSelection packets any time after LevelFinalize packet. Upon receiving the packet, a translucent cuboid should appear in the world. The cuboid may feature a plain or "grid" texture. Selections that extend outside the map may be either ignored or clipped to fit. Selections with inconsistent coordinates (e.g. where StartX<EndX) may either be ignored or re-ordered. Out-of-range values for Red, Green, Blue, and Opacity should be clipped to fit the valid range. Supporting Opacity is optional: the client may opt to provide fixed opacity instead. When map changes (i.e. when LevelInitialize packet is received), all existing selections should be removed. RemoveSelection packets that refer to non-existent SelectionIDs should be ignored.
- Server behavior: All given coordinates must be contained within the map. End coordinates should be higher or equal than start coordinates.
MakeSelection packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x1A (26)
SelectionID byte 0
Numeric ID of the selection. Between 0 and 127. Label string SomeZone
Text label associated with the selection StartX short 1
X coordinate of the starting point StartY short 2
Y coordinate of the starting point StartZ short 3
Z coordinate of the starting point EndX short 5
X coordinate of the ending point EndY short 6
Y coordinate of the ending point EndZ short 7
Z coordinate of the ending point Red short 255
Between 0 and 255. Green short 34
Between 0 and 255. Blue short 128
Between 0 and 255. Opacity short 255
0 = fully transparent 255 = fully opaque
Total Size: 86 bytes
RemoveSelection packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x1B (27)
SelectionID byte 0
Total Size: 2 bytes
BlockPermissions
- This extension allows the server to instruct the player that certain block types are allowed/disallowed to be placed or deleted.
- Motivation: To prevent players from inadvertently placing or removing prohibited block types (e.g. water, lava, grass, admincrete), before it even reaches the server.
- Client behavior: Client should prevent placement of prohibited block types (by graying out or hiding blocks in block-selection screen, or any other effective means). Client should prevent player from deleting prohibited block types. Client must be ready to receive SetBlockPermission packet after map load (LevelFinalize packet). Permission changes should take effect as soon as packet is received. Admincrete (solid block) permissions set by SetBlockPermission must always override permission set by ServerIdentification and UpdateUserType packets. If BlockType is set to
0
, given permissions should affect ALL block types at once, overriding permissions set by any earlier packets. Permissions must persist between map changes. Client may optionally warn the player attempting to place/delete prohibited blocks via sound effect, visual effect, chat message, etc. - Server behavior: Server may send SetBlockPermission packets any time after map load (LevelFinalize packet). Any valid block ID may be specified for BlockType, including custom blocks (if CustomBlocks extension is mutually supported). BlockType may be set to
0
to set permissions for ALL block types at once. Server must not assume that client is compliant/obedient, and server must still verify each SetBlock packet coming from the client. What to do with non-complying clients (kick or warn) is up to you.
SetBlockPermission packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x1C (28)
BlockType byte 8
Block's numeric ID (anything between 1 and max defined block). AllowPlacement byte 0
0 = Prohibited 1 = Allowed
AllowDeletion byte 0
0 = Prohibited 1 = Allowed
Total Size: 4 bytes
ChangeModel
- Allows changing appearance of player models in supporting clients.
- Client behavior: The client will receive a EntityID and a string value containing the model name. The client will then change the model of the player whose ID is the same as the received AddEntity or ExtAddEntity packet. The model name will be parsed by the model manager and the model changed in game. If the model does not exists in the model manager or is 0-length, change the model back to humanoid. Alternatively, you can send the client an int converted to a string which represents a valid Block ID. An EntityID of -1 (255 unsigned) indicates the player's own model.
- Server behavior: The server will send a EntityID and then a ModelName to the client for a desired player. The model name must exist in the client and not be 0-length or default (humanoid) will be used instead.
ChangeModel Packet
Packet ID Field Name Field Type Example Notes 0x1D (29)
EntityID byte 5 Between 0 and 127. ModelName string spider
The name of the model to be used OR a valid Block ID as a string. Total Size: 66 bytes
Available models
- Client can render any or none of the below, but it is down to the client to handle what can and cannot be rendered if the packet is recieved
Model Name Model String Chicken chicken
Block Model A valid block ID as a string Creeper creeper
Crocodile croc
Humanoid humanoid
(or an invalid model name)Pig pig
Printer printer
Sheep sheep
Skeleton Archer skeleton
Spider spider
Zombie zombie
EnvMapAppearance
- This extension allows the server to specify custom terrain textures, and tweak appearance of map edges.
- Motivation: To provide more ways to customize map appearance, including functionality that's currently provided by World of Minecraft's scheme.
- Client behavior: Client must be able to receive EnvSetMapAppearance packets any time during level load (after the first LevelDataChunk packet is received and until the LevelFinalize packet is received). If the TextureURL field is blank or if the given file could not be loaded for any reason, then the texture pack should be reset to client's default. If an unsupported block ID is given for SideBlock or EdgeBlock, it should be ignored. Given SideLevel value should be adjusted to fit between
0
andMapDepth
, if necessary. - Server behavior: Server may send EnvSetMapAppearance packets after the last LevelDataChunk packet is sent for a level. Server should not use any custom block IDs unless the client declared the appropriate CustomBlocks support level. To reset the texture pack to default value, server should send an EnvMapAppearance packet with empty string for TextureURL. To reset other fields, server should simply use the default values (listed below).
- Block type restrictions: Only solid blocks are allowed to be used for SideBlock and EdgeBlock. Sprites (Sapling, Dandelion, Rose, BrownMushroom, RedMushroom, Rope, Fire) partial-height blocks (Slab, CobblestoneSlab, Snow), and transparent blocks (Air, Leaves, Glass) cannot be used for those fields.
EnvSetMapAppearance packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x1E (30)
TextureURL string http://somesite.net/terrain.png
Skin's full URL. Must be an HTTP URL, ending with .png, and served with
image/png
mime type.SideBlock byte 7
Block ID. Default value is 7 (Admincrete). EdgeBlock byte 8
Block ID. Default value is 8 (Water). SideLevel short 31
Elevation from bottom of the map, in blocks. Value should be between
0
andMapDepth
. Default value isMapDepth/2
.Total Size: 69 bytes
EnvWeatherType
- This extension allows the server to trigger special weather conditions (like rain and snow) on demand.
- Motivation: To allow the server to give worlds/maps a unique feel with weather effects, e.g. for adventure maps.
- Client behavior: Client must be able to receive EnvWeather packets at any time after the first LevelDataChunk packet is received, and apply these changes immediately. If an unrecognized or unsupported WeatherType field is given, no action is needed.
- Server behavior: Server may send EnvSetColor packets to connected clients at any time after the first LevelDataChunk packet is sent.
EnvSetWeatherType Packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x1F (31)
WeatherType byte 1
Enumeration of weather types - 0 = sunny
- 1 = raining
- 2 = snowing
Total Size: 2 bytes
HackControl
- This extension allows the server to control cheats/hacks in the client.
- Motivation: To allow fine-grained control over cheats/hacks on multi-world servers.
- Client behavior: Client must be able to receive HackControl packets at any time after the first LevelDataChunk packet is received, and apply these changes immediately. Unrecognized or unsupported values for any field should be ignored. Clients may approximate JumpHeight by rounding down to the nearest half-block (i.e. nearest multiple of 16), if needed. If a negative value is given for JumpHeight, client should reset jump height to its default setting (around
40
in vanilla Minecraft). - Server behavior: Server may send HackControl packets to connected clients at any time after the first LevelDataChunk packet is sent.
HackControl Packet
- Server to Client
Packet ID Field Name Field Type Example Notes 0x20 (32)
Flying byte 0
- 0 = Prevent player from flying
- 1 = Allow flying
NoClip byte 0
- 0 = Prevent player from no-clipping (passing through solid blocks)
- 1 = Allow no-clipping
Speeding byte 0
- 0 = Only allow normal walking speed.
- 1 = Allow moving at any speeds.
SpawnControl byte 1
- 0 = Prevent player from pressing [R] to respawn, or using [Enter] to change spawn.
- 1 = Allow player to respawn / change spawn.
ThirdPersonView byte 1
- 0 = Disallow third-person view (only first-person view allowed).
- 1 = Allow third-person view.
JumpHeight short 40
Maximum height, in terms of player movement units (1/32nds of a block), to which the player is allowed to jump. Negative value (e.g.
-1
) means that the client should use its default jump height.Total Size: 8 bytes
MessageTypes
- This extension adds new ways of presenting messages in the client.
- Motivation: To enhance the display of announcements and status information, and to reduce chat clutter.
- Client behavior: When this extension is mutually supported, the PlayerID field of the standard server-to-client Message packet should be treated as a MessageType code. Unrecognized or unsupported codes may be ignored (in which case the message should be presented as a regular chat message). When connected to non-supporting servers, this field should be ignored.
- Server behavior: Server may use the PlayerID field of the Message packet to set a MessageType. For non-supporting clients, this field should always be set to
0
.
MessageType Meaning Suggested Implementation 0
Chat Normal message, shown in the chat area. 1
Status1 Shown persistently in the top-right corner of the screen, in regular font. 2
Status2 Shown persistently just below Status1 3
Status3 Shown persistently just below Status2 11
BottomRight1 Shown persistently in the bottom-right corner of the screen, in regular font. 12
BottomRight2 Shown persistently just above BottomRight1 13
BottomRight3 Shown persistently just above BottomRight2 100
Announcement Pops up in larger font near the top-center of the screen. Fades out after a few seconds.
- This extension does not define any new packets.