Codec and content type changes
26.1.2 moves book content loading onto codecs. If you maintain custom page types, custom loaders, or hand-written JSON content, this is the migration you need.
Summary
The old loader-based setup was replaced by typed registries backed by codecs and stream codecs. In practice that means:
- custom page types are now registered with
BookPageTypeRegistry - (builtin and custom) page classes now declare
ID,CODEC, andSTREAM_CODEC - page instances now return a
BookPageType<?>fromtype()instead of an id fromgetType() - raw JSON content now uses more explicit ids and types
Custom page registration changed
If you previously registered custom pages through LoaderRegistry.registerPageLoader(...), that registration path is gone.
Instead, create a small registry content container class and register your page type with BookPageTypeRegistry.register(...).
See these real migrations:
The pattern is:
- create a static
BookPageType<T>field per custom page - register it with page
ID,CODEC, andSTREAM_CODEC - call your registry class'
bootstrap()during common setup so the class loads
That replaces the old PageLoaders class entirely.
Custom page classes changed
Each custom page class now owns its serialization setup.
See these examples:
- Occultism:
BookSpiritFireRecipePage,BookBindingCraftingRecipePage - Theurgy:
BookAccumulationRecipePage,BookCalcinationRecipePage
Typical changes:
- add a static
ID - add a static
CODEC - add a static
STREAM_CODEC - remove old
fromJson(...)andfromNetwork(...)helpers - replace
getType()withtype()and return your registeredBookPageType<?> - if you override
toNetwork(...), delegate to yourSTREAM_CODEC
For built-in reference, see BookPageType.
Datagen page models changed
If you generate custom pages in code, update your page models as well.
BookRecipePageModel now expects subclasses to construct the final runtime page through createPage(...).
See these migrations:
- Occultism:
BookSpiritFireRecipePageModel,BookRitualRecipePageModel - Theurgy:
BookAccumulationRecipePageModel,BookLiquefactionRecipePageModel
In most cases the change is small:
- keep using your page
IDas the model type id - implement
createPage(BookRecipePage.JsonDataHolder common) - return the concrete runtime page instance from that method
Raw JSON content is now more explicit
The built-in demo content is a good reference for the new format:
The main JSON-facing changes are:
- entries now have an explicit top-level
type - content entries now have an explicit top-level
id - ids that used to be written as relative paths should now generally be fully qualified, for example
modonomicon:features/recipe - references such as
category,entry,entry_id,category_to_open,multiblock_id, andleaflet_entryshould use namespaced ids - many fields with default values are no longer emitted in generated JSON
So if your old JSON used values like features, features/recipe, or demo_block_entity, update them to full ids such as modonomicon:features, modonomicon:features/recipe, and modonomicon:demo_block_entity.
Multiblock matcher code changed too
If you interact with multiblock matchers in code, note that downstream integrations also had to update matcher type checks. See these examples:
Use stateMatcher().type() and compare against registry entries like StateMatcherTypeRegistry.ANY or StateMatcherTypeRegistry.DISPLAY.
Do not rely on the old getType() plus matcher-class constants pattern.
Recommended migration checklist
- Delete old custom
PageLoadersusage. - Register each custom page with
BookPageTypeRegistry.register(...). - Add
ID,CODEC, andSTREAM_CODECto each custom page class. - Replace
getType()withtype(). - Update datagen page models to implement
createPage(...). - Review hand-written JSON for explicit
typeand namespaced ids. - If you touch multiblock matcher code, switch to
stateMatcher().type()and the new registry constants.
After that, re-run datagen and compare your output against the built-in demo content.