Difference between revisions of "Data types"
(added Position description to the table) 
(added “encodes” for float and double) 

Line 37:  Line 37:  
! float  ! float  
 4   4  
+   [[wikipedia:Singleprecision floatingpoint formatSingleprecision 32bit IEEE 754 floating point]]  
    
−  
    
! double  ! double  
 8   8  
+   [[wikipedia:Doubleprecision floatingpoint formatDoubleprecision 64bit IEEE 754 floating point]]  
    
−  
    
! string  ! string 
Revision as of 20:22, 20 January 2015
All data sent over the network is bigendian, that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are littleendian, therefore it may be necessary to change the endianness before sending data over the network.
Other than 'String' and 'Metadata', which are decoded with a custom function, these data formats are identical to those provided by the Java classes DataInputStream and DataOutputStream.
Name  Size (bytes)  Encodes  Notes 

bool  1  false or true  Value can be either true (0x01 ) or false (0x00 )

byte  1  128 to 127  Signed 8bit integer, two's complement 
short  2  32768 to 32767  Signed 16bit integer, two's complement 
int  4  2147483648 to 2147483647  Signed 32bit integer, two's complement 
long  8  9223372036854775808 to 9223372036854775807  Signed 64bit integer, two's complement 
float  4  Singleprecision 32bit IEEE 754 floating point  
double  8  Doubleprecision 64bit IEEE 754 floating point  
string  ≥ 1 ≤ 2147483652 
A sequence of Unicode code points  UTF8 string prefixed with its length as a VarInt 
VarInt  ≥ 1 ≤ 5 
2147483648 to 2147483647  Protocol Buffer Varint, encoding a two's complement signed 32bit integer 
VarLong  ≥ 1 ≤ 10 
9223372036854775808 to 9223372036854775807  Protocol Buffer Varint, encoding a two's complement signed 64bit integer 
metadata  Varies  See this  
Slot Data  Varies  See slot data  
Position  8  integer/block position: x (33554432 to 33554431), y (2048 to 2047), z (33554432 to 33554431)  x as a 26bit integer, followed by y as a 12bit integer, followed by z as a 26bit integer (all signed, two's complement). See also the section below. 
UUID  16  A UUID  The vanilla Minecraft server internally sends this as two longs.
this.writeLong(uuid.getMostSignificantBits()); this.writeLong(uuid.getLeastSignificantBits()); 
Position
64bit long split in to three parts
x: 26 MSBs
z: 26 LSBs
y: 12 bits between them
Encoded as followed:
((x & 0x3FFFFFF) << 38)  ((y & 0xFFF) << 26)  (z & 0x3FFFFFF)
And decoded as:
long val; // Encoded value x = val >> 38; y = (val >> 26) & 0xFFF z = val << 38 >> 38
Fixedpoint numbers
Some fields may be stored as fixedpoint numbers, where a certain number of bits represents the signed integer part (number to the left of the decimal point) and the rest represents the fractional part (to the right). Floating points (float and double), in contrast, keep the number itself (mantissa) in one chunk, while the location of the decimal point (exponent) is stored beside it.
Essentially, while fixedpoint numbers have lower range than floating points, their fractional precision is greater for higher values. This makes them ideal for representing global coordinates of an entity in Minecraft, as it's more important to store the integer part accurately than position them more precisely within a single block (or meter).
Coordinates are often represented as a 32bit integer, where 5 of the leastsignificant bits are dedicated to the fractional part, and the rest store the integer part.
Java lacks support for fractional integers directly, but you can represent them as integers. To convert from a double to this integer representation, use the following formulas:
abs_int = (int)double * 32;
And back again:
double = (double)abs_int / 32;