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));