Codecs
A codec reads JSON and BSON, writes BSON, and recursively validates one completed value graph. Codecs are useful for components, persistence records, command data, and asset value types.
C# Generation
Use annotations when your module owns the C# type. Classes, records, and structs that receive generated members must be partial.
[GenerateCodec(NameStyle = CodecNameStyle.CamelCase)]
[CodecValidator<EnergyComponentValidator>]
public partial struct EnergyComponent
{
[CodecValidator<NonNegativeIntValidator>]
public int Current { get; set; }
[CodecAlias("maximum", UntilVersion = 0)]
[CodecValidator<PositiveIntValidator>]
public int Capacity { get; set; }
[CodecVersion(SinceVersion = 1)]
public bool Regenerates { get; set; }
[CodecIgnore]
public int Revision { get; set; }
}
The generator adds a public Codec property. The __Shard* members are hidden from editor completion and reserved for generated code.
var energy = EnergyComponent.Codec.DecodeJson(json);
EnergyComponent.Codec.Validate(energy);
EnergyComponent.Codec.EncodeBson(destination, energy);
These overloads use codec version zero. Pass a CodecContext when the operation needs another version or when the caller must inspect warnings and attributed diagnostics.
var context = new CodecContext(version: 1);
var current = EnergyComponent.Codec.DecodeJson(json, context);
Codec<T> has no JSON writer. JSON is an authoring format for assets, while writable persistence paths use BSON.
Validation and Normalization
[CodecValidator<TValidator>] attaches a reusable validator to a generated type or member. The validator implements ICodecValidator<T> and reports failures through the active CodecContext.
public sealed class PositiveIntValidator : ICodecValidator<int>
{
public static void Validate(in int value, CodecContext context)
{
if (value <= 0)
{
context.Fail("The value must be greater than zero.");
}
}
}
[CodecValidate] marks the type's one local validation method. Use it when a check compares several members or belongs only to that type.
[CodecValidate]
private static void Validate(in CosmeticAsset value, CodecContext context)
{
if (value.Variants is { Length: 0 })
{
context.Fail("A cosmetic needs at least one texture variant.");
}
}
[CodecNormalize] marks one deterministic transformation that runs after construction and before final validation. Keep the transformation local to the value, since registry lookups and other host work belong in an asset callback or module phase.
Schema Imports
Use a schema import when Hytale or another schema source owns the value shape. The project lists imports in schema/manifest.json:
{
"formatVersion": 1,
"imports": [
{
"roots": ["examples/ImportedBadgeAsset.json"],
"overlay": "codecs-example.codec-overlay.json",
"generatedNamespace": "Shard.Examples.CodecsExample.Schema"
}
]
}
The schema supplies the value shape and its constraints. The overlay records reviewed corrections and any asset behavior that the schema does not express. A root imported only as a value exposes Type.Codec; when the overlay also declares an asset family, generation adds the members described in the Assets guide.