Skip to main content
Version: 26.1.2 (Latest)

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, and STREAM_CODEC
  • page instances now return a BookPageType<?> from type() instead of an id from getType()
  • 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:

  1. create a static BookPageType<T> field per custom page
  2. register it with page ID, CODEC, and STREAM_CODEC
  3. 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:

Typical changes:

  • add a static ID
  • add a static CODEC
  • add a static STREAM_CODEC
  • remove old fromJson(...) and fromNetwork(...) helpers
  • replace getType() with type() and return your registered BookPageType<?>
  • if you override toNetwork(...), delegate to your STREAM_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:

In most cases the change is small:

  • keep using your page ID as 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, and leaflet_entry should 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.

  1. Delete old custom PageLoaders usage.
  2. Register each custom page with BookPageTypeRegistry.register(...).
  3. Add ID, CODEC, and STREAM_CODEC to each custom page class.
  4. Replace getType() with type().
  5. Update datagen page models to implement createPage(...).
  6. Review hand-written JSON for explicit type and namespaced ids.
  7. 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.