Desarrolladores
10 TOP-LEVEL ITEMSMultiCodec
MultiCodec<T> permite que un mismo tipo de dato soporte varias formas serializadas. Prueba sus codecs internos en orden y devuelve el primer resultado exitoso.
Esta necesidad aparece constantemente en sistemas de datos al estilo vanilla, pero Mojang no proporciona un "codec unión ordenado" ya preparado. MultiCodec de Croparia IF llena justo ese hueco.
Idea básica
MultiCodec<T> es esencialmente un ArrayList<TestedCodec<? extends T>> que además implementa Codec<T>.
Su comportamiento es:
- probar el primer codec
- si falla, registrar el error
- probar el siguiente codec
- continuar hasta que uno tenga éxito
- si todos fallan, combinar sus errores y devolver el fallo conjunto
Así que lo importante no es solo que pueda contener varios codecs, sino que su orden importa.
Las ramas anteriores tienen la primera oportunidad de consumir la entrada, así que conviene pensar bien:
- qué formato es más específico
- qué formato es más amplio
- si los mensajes de error seguirán ayudando durante la depuración
Cuándo usarlo
Casos de uso comunes:
- un valor puede escribirse como valor único o como lista
- un objeto puede usar una forma abreviada o una forma completa
- formatos antiguos y nuevos de configuración deben coexistir
Por ejemplo, un campo puede aceptar:
"minecraft:stone"o:
["minecraft:stone", "minecraft:dirt"]Ese es exactamente el tipo de situación donde MultiCodec encaja bien.
Uso básico
La vía de construcción más común es CodecUtil.of(...):
MultiCodec<List<String>> codec = CodecUtil.of(
Codec.STRING.listOf(),
Codec.STRING.xmap(List::of, List::getFirst)
);Esto significa:
- primero intentar decodificar la entrada como lista
- si falla, intentarla como una sola cadena
- normalizar ambas formas a
List<String>
En el día a día suele ser mejor usar CodecUtil.listOf(...) directamente, porque esa utilidad ya expresa bien el patrón "elemento único o lista".
Relación con TestedCodec
MultiCodec solo decide el orden. No decide si una rama es razonable para la entrada actual. Esa parte le corresponde a TestedCodec.
Dentro de CodecUtil.of(...), los codecs normales se envuelven automáticamente en TestedCodec, así que puedes elegir entre:
- pasar codecs normales
- pasar ramas
TestedCodecque ya tengan su filtrado personalizado
Cuando los límites entre ramas pueden describirse bien, las comprobaciones explícitas con TestedCodec suelen hacer el resultado:
- más fácil de depurar
- más seguro frente a ramas demasiado amplias
- más estable para compatibilidad de formatos a largo plazo
CodecUtil.listOf(...)
CodecUtil.listOf(codec) es la ayuda más común basada en MultiCodec. Permite que un valor acepte:
- un solo elemento
- una lista de elementos
y siempre devuelve List<E>.
MultiCodec<List<Identifier>> codec = CodecUtil.listOf(Identifier.CODEC);Ese codec puede aceptar:
"croparia:gem_earth"y:
["croparia:gem_earth", "croparia:gem_water"]La idea no es solo ahorrar unas líneas, sino hacer que un patrón de compatibilidad muy frecuente se comporte igual en todas partes.
Cómo elegir el orden de las ramas
El orden de las ramas es la decisión principal en MultiCodec. Una regla útil suele ser:
- poner primero los formatos más específicos
- dejar después los formatos más amplios y más propensos a "tragarse" entradas por error
Por ejemplo:
- una forma de objeto suele ser más específica que una forma de cadena
- una forma en lista suele ser más específica que una forma de valor único
Si el orden se invierte, una rama demasiado flexible puede tener éxito antes de tiempo e impedir que se pruebe la rama más adecuada.
Consejos
MultiCodecfunciona mejor para "un mismo significado, varias escrituras". No sustituye al modelado normal de datos.- Si el número de ramas sigue creciendo, a menudo es mejor estrechar el modelo primero en lugar de seguir apilando alternativas.
- Cuando una forma de rama se detecta fácilmente, combina
MultiCodeccon TestedCodec. - Si solo necesitas "valor único o lista", prefiere CodecUtil.listOf.