Skip to content

Serialization (Codec) System Overview

The Codec System provides serialization and deserialization for BSON and JSON formats. It uses a type-safe, builder-based approach with support for versioning, validation, polymorphism, and automatic JSON schema generation.

  • Core: com.hypixel.hytale.codec
  • Builders: com.hypixel.hytale.codec.builder
  • Built-in Codecs: com.hypixel.hytale.codec.codecs
  • Validation: com.hypixel.hytale.codec.validation
  • Asset Codecs: com.hypixel.hytale.assetstore.codec
  • Protocol Codecs: com.hypixel.hytale.server.core.codec
  • Type safety - Compile-time checked serialization with generics
  • Dual format support - Single codec handles both BSON and JSON
  • Validation - Built-in validators enforce constraints at decode time
  • Versioning - Schema evolution with field-level version ranges
  • Schema generation - Automatic JSON schema output via toSchema()
  • Inheritance - Parent/child codec relationships with field merging
  • Polymorphism - Type dispatch via discriminator fields
flowchart TB
    subgraph Core["Core Codec System"]
        Interface["Codec&lt;T&gt;<br/>(Interface)"]
        Keyed["KeyedCodec&lt;T&gt;<br/>(Field name + codec)"]
        Builder["BuilderCodec&lt;T&gt;<br/>(Complex objects)"]
        FunctionCodec["FunctionCodec&lt;T,R&gt;<br/>(Transform)"]
    end

    subgraph Dispatch["Polymorphic Dispatch"]
        CodecMap["CodecMapCodec&lt;T&gt;"]
        StringCodecMap["StringCodecMapCodec&lt;T,C&gt;"]
    end

    subgraph Collections["Collection Codecs"]
        ArrayCodec["ArrayCodec&lt;T&gt;"]
        MapCodec["MapCodec&lt;V,M&gt;"]
        SetCodec["SetCodec&lt;V,S&gt;"]
        EnumCodec["EnumCodec&lt;T&gt;"]
    end

    subgraph Assets["Asset Codecs"]
        AssetCodec["AssetCodec&lt;K,T&gt;"]
        AssetBuilder["AssetBuilderCodec&lt;K,T&gt;"]
    end

    Builder --> Interface
    FunctionCodec --> Interface
    CodecMap --> StringCodecMap
    StringCodecMap --> Interface
    AssetBuilder --> Builder
    AssetBuilder -.-> AssetCodec
    ArrayCodec --> Interface
    MapCodec --> Interface
    SetCodec --> Interface
    EnumCodec --> Interface

The main serialization interface. Every codec implements three operations: decode from BSON, encode to BSON, and decode from JSON.

package com.hypixel.hytale.codec;
import com.hypixel.hytale.codec.schema.SchemaConvertable;
import com.hypixel.hytale.codec.util.RawJsonReader;
import org.bson.BsonValue;
import java.io.IOException;
public interface Codec<T> extends RawJsonCodec<T>, SchemaConvertable<T> {
T decode(BsonValue bsonValue, ExtraInfo extraInfo);
BsonValue encode(T value, ExtraInfo extraInfo);
T decodeJson(RawJsonReader reader, ExtraInfo extraInfo) throws IOException;
}

Wraps a Codec<T> with a named key for use as a field within a BsonDocument. Key names must start with an uppercase letter.

package com.hypixel.hytale.codec;
import org.bson.BsonDocument;
import java.util.Optional;
public class KeyedCodec<T> {
public KeyedCodec(String key, Codec<T> codec);
public KeyedCodec(String key, Codec<T> codec, boolean required);
}
MethodReturn TypeDescription
get(BsonDocument, ExtraInfo)Optional<T>Get value, empty if missing
getNow(BsonDocument, ExtraInfo)TGet value, throws if missing
getOrNull(BsonDocument, ExtraInfo)TGet value or null
getOrDefault(BsonDocument, ExtraInfo, T)TGet value or default
getAndInherit(BsonDocument, T, ExtraInfo)Optional<T>Get with parent inheritance
put(BsonDocument, T, ExtraInfo)voidEncode and put into document
getKey()StringGet the field name
getChildCodec()Codec<T>Get the wrapped codec
isRequired()booleanWhether the field is required
CodecJava TypeDescription
Codec.STRINGStringText values
Codec.BOOLEANBooleanTrue/false
Codec.INTEGERInteger32-bit integers
Codec.LONGLong64-bit integers
Codec.FLOATFloat32-bit floats
Codec.DOUBLEDouble64-bit doubles
Codec.BYTEByte8-bit integers
Codec.SHORTShort16-bit integers
CodecJava Type
Codec.STRING_ARRAYString[]
Codec.INT_ARRAYint[]
Codec.LONG_ARRAYlong[]
Codec.FLOAT_ARRAYfloat[]
Codec.DOUBLE_ARRAYdouble[]
CodecJava TypeDescription
Codec.UUID_BINARYUUIDBinary UUID format
Codec.UUID_STRINGUUIDString UUID format
Codec.PATHPathFile path (via FunctionCodec)
Codec.INSTANTInstantISO-8601 timestamp
Codec.DURATIONDurationISO-8601 duration string
Codec.DURATION_SECONDSDurationDuration as seconds (double)
Codec.LOG_LEVELLevelJava logging level

ExtraInfo carries context through the entire encode/decode process. It tracks the current decode path, manages validation results, and provides thread-local access.

package com.hypixel.hytale.codec;
import com.hypixel.hytale.codec.validation.ValidationResults;
import java.util.List;
public class ExtraInfo {
public static final ThreadLocal<ExtraInfo> THREAD_LOCAL;
public void pushKey(String key);
public void popKey();
public String peekKey();
public int peekLine();
public int peekColumn();
public int getVersion();
public int getKeysSize();
public void addUnknownKey(String key);
public List<String> getUnknownKeys();
public ValidationResults getValidationResults();
}

The path tracking (pushKey/popKey) produces dot-separated paths like "MyField.SubField.0" that appear in error messages, making it easy to locate problems in deeply nested structures.

  • Component Codecs - BuilderCodec, collection codecs, validation, versioning, and ProtocolCodecs
  • Asset Codecs - AssetBuilderCodec, AssetCodecMapCodec, and ContainedAssetCodec
  • Creating Custom Codecs - Step-by-step guide to building your own codecs
  • Registries - Codec registration in the registry system