This website is unofficial. For the official Minestom documentation, go to minestom.net.
Skip to content

Network Buffers ​

Network buffers read and write binary data sequentially. They maintain separate read and write positions and provide type-safe serialization.

java
NetworkBuffer buffer = NetworkBuffer.resizableBuffer();

// Writing
buffer.write(NetworkBuffer.STRING, "Hello");
buffer.write(NetworkBuffer.VAR_INT, 42);
buffer.write(NetworkBuffer.UUID, playerId);

// Reading
String message = buffer.read(NetworkBuffer.STRING);
int value = buffer.read(NetworkBuffer.VAR_INT);
UUID id = buffer.read(NetworkBuffer.UUID);

Creating Buffers ​

java
// Resizable buffer that grows automatically (default 256 bytes initial)
NetworkBuffer buffer = NetworkBuffer.resizableBuffer();

// Resizable with custom initial size
NetworkBuffer buffer = NetworkBuffer.resizableBuffer(1024);

// Fixed-size buffer
NetworkBuffer buffer = NetworkBuffer.staticBuffer(512);

// Create a fixed-size buffer initialized from a byte array
byte[] data = new byte[]{1, 2, 3, 4};
NetworkBuffer buffer = NetworkBuffer.wrap(data, 0, data.length);

NetworkBuffer.wrap(...) copies the provided bytes into the buffer; it does not share the original byte[].

Built-in Types ​

Primitives ​

TypeJava TypeSizeDescription
BOOLEANBoolean1 byteBoolean value
BYTEByte1 byteSigned 8-bit integer
UNSIGNED_BYTEShort1 byteUnsigned 8-bit integer (0-255)
SHORTShort2 bytesSigned 16-bit integer
UNSIGNED_SHORTInteger2 bytesUnsigned 16-bit integer (0-65535)
INTInteger4 bytesSigned 32-bit integer
UNSIGNED_INTLong4 bytesUnsigned 32-bit integer
LONGLong8 bytesSigned 64-bit integer
FLOATFloat4 bytes32-bit floating point
DOUBLEDouble8 bytes64-bit floating point
VAR_INTInteger1-5 bytesVariable-length integer
VAR_LONGLong1-10 bytesVariable-length long
OPTIONAL_VAR_INT@Nullable Integer1-5 bytesNullable VAR_INT; encodes 0 for absent, n+1 for n
VAR_INT_3Integer3 bytesFixed 3-byte VarInt, range 0–2²¹-1
UNITUnit0 bytesRepresents the absence of a value

VAR_INT and VAR_LONG encode small values in fewer bytes. Values 0-127 use 1 byte, larger values use up to 5 bytes (VAR_INT) or 10 bytes (VAR_LONG).

Strings and Text ​

TypeJava TypeDescription
STRINGStringUTF-8 string with VAR_INT length prefix
KEYKeyNamespaced key (e.g., minecraft:stone)
COMPONENTComponentAdventure text component in the standard network format
NBTBinaryTagNBT tag
NBT_COMPOUNDCompoundBinaryTagNBT compound tag
JSON_COMPONENTComponentAdventure text component as JSON string
STRING_TERMINATEDStringNull-terminated UTF-8 string
STRING_IO_UTF8StringModified UTF-8 string for stream I/O with a 2-byte length prefix (DataOutputStream.writeUTF compatible)

Positions and Vectors ​

TypeJava TypeDescription
BLOCK_POSITIONPointBlock coordinates packed into a long
OPT_BLOCK_POSITION@Nullable PointOptional block coordinates
POSPosPosition (double x, y, z) with rotation (float yaw, pitch)
VECTOR3PointThree floats (x, y, z)
VECTOR3DPointThree doubles (x, y, z)
VECTOR3IPointThree VAR_INTs (x, y, z)
VECTOR3BPointThree signed bytes (x, y, z)
LP_VECTOR3VecLossy-precision quantized vector
QUATERNIONfloat[]Rotation as four floats (x, y, z, w)

Arrays and Collections ​

TypeJava TypeDescription
BYTE_ARRAYbyte[]VAR_INT length, then bytes
LONG_ARRAYlong[]VAR_INT length, then longs
VAR_INT_ARRAYint[]VAR_INT length, then VAR_INT elements
VAR_LONG_ARRAYlong[]VAR_INT length, then VAR_LONG elements
RAW_BYTESbyte[]All remaining readable bytes

Other Types ​

TypeJava TypeDescription
UUIDUUIDUUID stored as two longs
BITSETBitSetJava BitSet
INSTANT_MSInstantInstant as milliseconds since epoch
OPT_CHAT@Nullable ComponentOptional Adventure text component
DIRECTIONDirectionDirection enum (including up/down, by ordinal)
POSEEntityPoseEntity pose (by ordinal)
PUBLIC_KEYPublicKeyRSA public key as byte array

Transforming Types ​

.transform() converts between a network type and your custom type.

java
NetworkBuffer.Type<PotionType> POTION_TYPE =
    NetworkBuffer.VAR_INT.transform(
        PotionType::fromId,
        PotionType::id
    );

buffer.write(POTION_TYPE, potionType);
PotionType type = buffer.read(POTION_TYPE);

Enums ​

Enums can be serialized by ordinal using NetworkBuffer.Enum(). Unlike Codec.Enum(), which encodes by name, this uses the enum's numeric ordinal as a VAR_INT.

java
NetworkBuffer.Type<Direction> DIRECTION = NetworkBuffer.Enum(Direction.class);

buffer.write(DIRECTION, Direction.NORTH);
Direction dir = buffer.read(DIRECTION);

For EnumSets, use NetworkBuffer.EnumSet():

java
NetworkBuffer.Type<EnumSet<Feature>> FEATURES = NetworkBuffer.EnumSet(Feature.class);

Optional Types ​

.optional() wraps a type to allow null values. Writes a boolean (present/absent) followed by the value if present.

java
NetworkBuffer.Type<@Nullable Component> OPT_COMPONENT =
    NetworkBuffer.COMPONENT.optional();

buffer.write(OPT_COMPONENT, null);
buffer.write(OPT_COMPONENT, someComponent);

@Nullable Component component = buffer.read(OPT_COMPONENT);

Collections ​

.list() creates a list type. .mapValue() creates a map type whose keys use the receiver type and whose values use the provided type. Both accept a maximum size used during reads to reject oversized payloads.

java
NetworkBuffer.Type<List<String>> STRING_LIST =
    NetworkBuffer.STRING.list(Short.MAX_VALUE);

buffer.write(STRING_LIST, List.of("a", "b", "c"));
List<String> strings = buffer.read(STRING_LIST);

NetworkBuffer.Type<Map<String, Integer>> STRING_INT_MAP =
    NetworkBuffer.STRING.mapValue(NetworkBuffer.INT, Short.MAX_VALUE);

buffer.write(STRING_INT_MAP, Map.of("health", 20, "armor", 5));

Templates ​

Templates serialize structured objects such as records. Alternate between type and getter pairs, ending with a constructor or factory function. Overloads are provided for up to 20 fields.

java
record Particle(Point position, int id, float scale) {
    static final NetworkBuffer.Type<Particle> NETWORK_TYPE =
        NetworkBufferTemplate.template(
            NetworkBuffer.BLOCK_POSITION, Particle::position,
            NetworkBuffer.VAR_INT, Particle::id,
            NetworkBuffer.FLOAT, Particle::scale,
            Particle::new
        );
}

buffer.write(Particle.NETWORK_TYPE, particle);
Particle particle = buffer.read(Particle.NETWORK_TYPE);

Templates support optional and nested types:

java
record PlayerInfo(
    UUID uuid,
    String name,
    List<Property> properties,
    @Nullable Component displayName,
    int ping
) {
    static final NetworkBuffer.Type<PlayerInfo> NETWORK_TYPE =
        NetworkBufferTemplate.template(
            NetworkBuffer.UUID, PlayerInfo::uuid,
            NetworkBuffer.STRING, PlayerInfo::name,
            Property.NETWORK_TYPE.list(16), PlayerInfo::properties,
            NetworkBuffer.COMPONENT.optional(), PlayerInfo::displayName,
            NetworkBuffer.VAR_INT, PlayerInfo::ping,
            PlayerInfo::new
        );
}

Buffer Management ​

Query and modify read/write positions:

java
long writePos = buffer.writeIndex();
long readPos = buffer.readIndex();
buffer.writeIndex(100);
buffer.readIndex(50);

buffer.advanceWrite(10);
buffer.advanceRead(5);

long readable = buffer.readableBytes();
long writable = buffer.writableBytes();

buffer.clear();

Read/Write at Position ​

Read or write at a specific index without moving the current read/write positions:

java
buffer.writeAt(100, NetworkBuffer.INT, 42);
int value = buffer.readAt(100, NetworkBuffer.INT);

Extract Bytes ​

Extract the bytes consumed while a callback advances the read index:

java
byte[] bytes = buffer.extractBytes(buf -> {
    buf.read(NetworkBuffer.VAR_INT);
    buf.read(NetworkBuffer.STRING);
});

To serialize writes into a new byte array, use NetworkBuffer.makeArray(...) instead:

java
byte[] bytes = NetworkBuffer.makeArray(buf -> {
    buf.write(NetworkBuffer.VAR_INT, 42);
    buf.write(NetworkBuffer.STRING, "test");
});

Fixed-Length Bytes and Bounded BitSets ​

Create fixed-length byte-array types and bitset types with a maximum logical size:

java
NetworkBuffer.Type<byte[]> BYTES_16 = NetworkBuffer.FixedRawBytes(16);
NetworkBuffer.Type<BitSet> BITSET_64 = NetworkBuffer.FixedBitSet(64);

FixedBitSet(length) limits the highest set bit and reads up to (length + 7) / 8 bytes; it does not pad writes to a fixed-width byte array.

Either Types ​

Serialize one of two types. Prefixed by a boolean: true for the left variant, false for the right variant.

java
NetworkBuffer.Type<Either<String, Integer>> STRING_OR_INT = NetworkBuffer.Either(NetworkBuffer.STRING, NetworkBuffer.INT);
buffer.write(STRING_OR_INT, Either.left("hello"));
buffer.write(STRING_OR_INT, Either.right(67));