Skip to main content

Registries and Codecs

MiXianTu has two kinds of registries. Built-in registries hold the MapCodec implementations that a datapack selects with the type field, and are populated in Java code. Datapack registries are native Minecraft registries whose entries live in JSON files: Minecraft reads them while the world loads, and they are synchronised to the client by the registry system. Because they are read at world load, /reload does not re-read them — see Loading, Syncing and Debugging.

Built-In Type Registries​

Built-in registries use NeoForge's DeferredRegister<MapCodec<?>>, and a datapack is dispatched to the matching implementation through type:

public static final DeferredRegister<MapCodec<? extends Cost>> REGISTRY =
DeferredRegister.create(MxtRegistries.COST_TYPE, MiXianTu.MOD_ID);

The registry instances are declared in MxtRegistries, and their keys are declared once in MxtResourceKeys:

RegistryKeyContents
MxtRegistries.ABILITY_TYPEsaturn:ability_typeAbility type codecs.
MxtRegistries.ABILITY_TARGET_SELECTOR_TYPEsaturn:ability_target_selector_typeAbility target selector codecs.
MxtRegistries.COST_TYPEsaturn:cost_typeCost type codecs.
MxtRegistries.CURSE_TYPEmxt:curse_typeCurse type codecs.
MxtRegistries.DATA_STORAGE_TYPEsaturn:data_storage_typeStorage kind codecs; which kinds a host declares is decided by its own type (AbilityType.createComponents), and the built-in ones are registered in MxtDataStorages.
MxtRegistries.TRIGGER_TYPEsaturn:trigger_typeAbility trigger codecs.
MxtRegistries.NUMBER_PROVIDER_TYPEsaturn:number_provider_typeNumber provider codecs.
MxtRegistries.AURA_MAXIMUM_TYPEmxt:aura_maximum_typeAura maximum codecs.
MxtRegistries.FORMULA_FUNCTIONsaturn:formula_functionFormula functions available to expressions.
MxtRegistries.FORMULA_VARIABLEsaturn:formula_variableBuilt-in formula variables. Each entry reads a number out of the objects the formula context carries, and a data pack cannot add entries; the names are listed in Formula Variables.
MxtRegistries.RESOURCE_VALUE_PROVIDER_TYPEsaturn:resource_value_provider_typeResource value provider codecs.
MxtRegistries.ENTITY_ACTION_TYPEsaturn:entity_action_typeEntity action codecs.
MxtRegistries.BI_ENTITY_ACTION_TYPEsaturn:bi_entity_action_typeBi-entity action codecs.
MxtRegistries.BLOCK_ACTION_TYPEsaturn:block_action_typeBlock action codecs.
MxtRegistries.ITEM_ACTION_TYPEsaturn:item_action_typeItem action codecs.
MxtRegistries.ENTITY_CONDITION_TYPEsaturn:entity_condition_typeEntity condition codecs.
MxtRegistries.BI_ENTITY_CONDITION_TYPEsaturn:bi_entity_condition_typeBi-entity condition codecs.
MxtRegistries.BLOCK_CONDITION_TYPEsaturn:block_condition_typeBlock condition codecs.
MxtRegistries.ITEM_CONDITION_TYPEsaturn:item_condition_typeItem condition codecs.
MxtRegistries.DAMAGE_CONDITION_TYPEsaturn:damage_condition_typeDamage condition codecs.
MxtRegistries.RESOURCE_BAR_RENDER_DATA_TYPEsaturn:resource_bar_render_data_typeResource bar render data codecs.
MxtRegistries.MOUNT_RENDER_TYPEmxt:mount_render_typeMount renderer codecs.
MxtRegistries.RESOURCE_BAR_CONTEXTsaturn:resource_bar_contextResource bar contexts.
MxtRegistries.RESOURCE_BAR_VISIBILITY_TYPEsaturn:resource_bar_visibility_typeResource bar visibility codecs.
MxtRegistries.ITEM_MATCHER_ENTRY_TYPEsaturn:item_matcher_entry_typeItem matcher entry codecs.
MxtRegistries.FORMATION_ACTION_TYPEmxt:formation_action_typeFormation module codecs, dispatched by a module's type; the built-in ones are registered in MxtFormationActionTypes.
MxtRegistries.TIMELINE_ENTRY_TYPEsaturn:timeline_entry_typeTribulation timeline entry codecs, dispatched by an entry's type; the built-in ones are registered in MxtTimelineEntries.
MxtRegistries.SECRET_REALM_GENERATION_TYPEmxt:secret_realm_generation_typeSecret realm generation codecs.

The built-in types are grouped and registered by classes such as MxtEntityActions, MxtBiEntityActions, MxtBlockActions, MxtItemActions and MxtEntityConditions. Registering a new built-in type means providing a MapCodec and adding it to the matching DeferredRegister; a data pack never adds entries to these registries.

These registries are open to other mods: a third-party module may add its own codecs to any of them — the built-in trigger table documents this explicitly — and the new type ids then become available to datapacks.

Formula Variables​

saturn:formula_variable holds the built-in variables a formula can read. An entry implements FormulaVariable and reads its number out of the objects the FormulaContext carries, so nothing is precomputed:

MemberDescription
names()The exact names the variable provides. They are indexed once, and a name may only be claimed by a single variable; a collision is reported.
prefixes()Name prefixes the variable provides, each including its separator, such as caster_. A requested name that starts with a prefix is handed to the variable with that prefix removed.
value(key, suffix, context)The value for a name the variable claimed. key is the name or prefix that matched and suffix is what follows it, so caster_mxt_common arrives as key caster_ plus suffix mxt_common. Return Double.NaN to decline the name, which lets the next variable that claims it be asked; the resolver reports a declined or non-finite value once and continues with 0.

Register an entry with DeferredRegister.create(MxtRegistries.FORMULA_VARIABLE, MODID). Unavailable names and non-finite values go through FormulaDiagnostics, which logs the whole error in a development environment and one warning line per distinct message in production, so an addon does not need its own error policy; problems a codec can already see while parsing are reported as decode errors instead. FormulaNames flattens a registry ID into a formula identifier and keeps the resource and attribute name indexes.

A requested name is split into the variables that claim it once per expression, not once per evaluation: Expression keeps the resulting binding next to its compiled exp4j expression, so a formula evaluated every tick resolves each name a single time and afterwards only re-reads the values. The names themselves are documented in Formula Variables.

Datapack Registries​

Every registry the mod declares is listed — with its file directory, its purpose and every field — in JSON Data Formats. An addon normally adds entries to those registries rather than new registries.

Reading Registries​

MxtDatapackRegistries is the supported entry point for both the server and the synchronised client copy. Every read is a plain registry read: it filters nothing. Switching a definition off is load-time work — a neoforge:conditions block in the definition file keeps the entry out of the registry entirely — so an entry in the registry is an entry you can use (see Disabling a Definition).

MemberDescription
registries()Every registry key owned by the mod, in registration order.
get(key, id)Reads a definition value by ID.
holder(key, id)Resolves an entry while keeping its stable holder reference.
holders(key)Streams every entry of a registry.
holders(access, key) / holders(provider, key)Streams entries from a RegistryAccess or a HolderLookup.Provider, which is how the client reads the synchronised copy.
get(access, key, id)Reads a value from a client-synchronised lookup.
holderOrEmpty(key, id)The same as holder(key, id), but gives empty instead of throwing when no server is running.
isTagged(key, id, tagId) / isTagged(key, holder, tagId)Checks a native datapack tag on one entry.
size(key) / registry(key)The underlying Registry; only available while a server is running.
info

registry(key) and size(key) throw an IllegalStateException when no server is running. On the client, use the holders(access, key) and get(access, key, id) overloads that take the synchronised lookup instead.

Codecs​

A definition class exposes two codecs. CODEC reads and writes a Holder<Definition> reference and is what a field or another JSON file uses to point at a definition; DIRECT_CODEC reads and writes the whole object and is what a datapack registry uses for the entry itself. Read DIRECT_CODEC when you need the values of a definition, for example Resource.DIRECT_CODEC or ItemQuality.DIRECT_CODEC.

How the registries split into a content layer and a binding layer, what one definition passes through from its file to a settlement, and whether a component or a declaration wins, is in Data Loading.