Difference between revisions of "Data types"

From wiki.vg
Jump to navigation Jump to search
(Add 128-bit integer)
(I believe the term "absolute integer" is confusing. It sounds too much like the absolute value of an integer. Better to call them by their more formal name - fixed-point integers.)
Line 81: Line 81:
 
|}
 
|}
  
Some data may be stored as an "absolute integer", which is a more precise kind of integer, and a less precise kind of double.  The conversion from double to absolute integer is like so:
+
=== Fixed-point numbers ===
  
abs_int = (int)double * 32;
+
Some fields may be stored as [https://en.wikipedia.org/wiki/Fixed-point_arithmetic fixed-point 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 double9, in contrast, keep the number itself (mantissa) in one chunk, while the location of the decimal point (exponent) is stored beside it.
  
 +
Essentially, while fixed-point 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 32-bit integer, where 5 of the least-significant 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:
 
And back again:
  
double = (double)abs_int / 32;
+
  double = (double)abs_int / 32;
  
 
[[Category:Protocol Details]]
 
[[Category:Protocol Details]]
 
[[Category:Minecraft Modern]]
 
[[Category:Minecraft Modern]]

Revision as of 16:31, 25 September 2013

All data sent over the network is big-endian, that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, 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.

Size Range Notes
bool 1 0 or 1 Value can be either true (0x01) or false (0x00)
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
128-bit integer 16 0 to 340282366920938463463374607431768211455 Unsigned, two's complement

Used in 0x2C to transmit UUIDs.

The vanilla Minecraft server internally sends this as two longs.

float 4

See this

Single-precision 32-bit IEEE 754 floating point
double 8

See this

Double-precision 64-bit IEEE 754 floating point
string ≥ 2
≤ 240
N/A UTF-16 big-endian string prefixed by a short containing the length of the string in code units.

UTF-16 is a variable-length encoding, which means that a single Unicode code point (what most programmers think of as a "character") may be encoded by a variable number of code units.

UTF-16 encodes code points as either one or two 16 bit code units.

Characters in the Basic Multilingual Plane (U+0000 through U+FFFF inclusive) are encoded as one 16 bit code unit.

Characters in the other Unicode planes (U+10000 through U+10FFFF inclusive) are encoded as two 16 bit code units (a high/low "surrogate pair").

Therefore, the length in bytes of a string may be obtained by multiplying the number of code units by two, and the opposite operation may be performed by dividing by two.

However, since UTF-16 is variable-length, the number of code units is totally unrelated to the number of code points (i.e. "characters"), and you will actually have to decode the string to obtain this information.

It was historically believed that the Minecraft protocol used the fixed-width encoding UCS-2, however this has since been proven to be incorrect.

metadata Varies See this

Fixed-point numbers

Some fields may be stored as fixed-point 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 double9, in contrast, keep the number itself (mantissa) in one chunk, while the location of the decimal point (exponent) is stored beside it.

Essentially, while fixed-point 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 32-bit integer, where 5 of the least-significant 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;