Skip to content

Project-wide refactors/clean-ups, rewrite generators to use Fabric's data generation API#97

Open
eclipseisoffline wants to merge 41 commits into
masterfrom
datagen-rewrite
Open

Project-wide refactors/clean-ups, rewrite generators to use Fabric's data generation API#97
eclipseisoffline wants to merge 41 commits into
masterfrom
datagen-rewrite

Conversation

@eclipseisoffline

@eclipseisoffline eclipseisoffline commented Jul 1, 2026

Copy link
Copy Markdown
Member

This PR rewrites Geyser's mappings-generator to make use of Fabric Loom and Fabric's data generator API. With this, all mapping generators have been rewritten to better fit in the modern Minecraft and Java ecosystem. The code has received a broad clean-up and major improvements. PR highlights are:

  • The generator, and the individual generators, now have proper logging instead of using System.out.println statements, making it easier to identify problems.
    • Log statements have also been improved or added in many places.
  • The generated files are better organised and all contained within the mappings directory - the previous mappings submodule can now be found at mappings/mappings.
  • The generator will automatically download bedrock-samples at runtime (unless the current samples are accurate for the current bedrock version).
  • The generator will automatically download Bedrock palette files at runtime (unless the current files are accurate for the current bedrock version) (to be implemented, maybe).
  • The generator will automatically clone the mappings submodule if that is not done yet (to be implemented, maybe).
  • The generator will present a "files changed" report after running.
  • The generator runs faster in many cases.
    • Especially the generator for interaction mappings has improved massively in execution time.
  • Gradle tasks exist to run a subset of generators (e.g. MCPL generators only) (to be implemented).
  • The codebase has received many clean-ups and refactors, and huge classes have been split up, making it easier to read the code of current generators and write new generators as well.
  • Mixins may now be used easily in the codebase.

All the changes made in this PR will be noted below. A TO-DO list can be found at the end of the description.

Project-wide changes

  • The Gradle version has been bumped to 9.5 (will be bumped to 9.6 later).
  • A libs.versions.toml file is now used for library management.
  • The Gradle buildscripts have received clean-ups:
    • Switched from VanillaGradle to Fabric Loom.
    • Use Loom's download task for downloading palettes, instead of our own.
      • This task is public API in Fabric Loom.
      • The task to download bedrock-samples.zip, and the task to extract the resourcepack from it, have been removed, as this is now downloaded at runtime.
    • The -Dline.separator=\u00a JVM argument is given to the runDatagen task, to ensure the generated files use the same line endings everywhere.
  • The mappings submodule can now be found under the mappings directory, so at mappings/mappings.
    • Palette files are located at mappings/palettes.
    • The generator will generate other, untracked files in the mappings directory as well.
  • additional_offhand_items.json has been removed, as it is now tracked in the mappings repository.
  • generator_blocks.json has been removed, and its replacement is no longer tracked in VCS.
  • .gitattributes and .editorconfig files have been added.
  • .gitignore has been updated to reflect the changes in the project structure.

Codebase-wide changes

  • The project now uses nullability annotations provided by JSpecify, in line with Minecraft Java itself. All the code has been null-marked.
  • The code is now located in the org.geysermc.mappings package (was org.geysermc.generator).
    • This change was made because generator is now a package within org.geysermc.mappings (see below) - without this rename, the package name would have been org.geysermc.generator.generator, which can be confusing.
  • Most of the generator code has been reworked and split over multiple classes. Records and Mojang's codecs are now used widely across the codebase.
    • Switching to using Mojang's codecs has many benefits, however, if users still wish to create JsonElements or CompoundTags directly, they can do so by using MappingsCodecs.JSON_ELEMENT and CompoundTag.CODEC respectively.
    • A lot of code duplication has been removed by abstracting code patterns and creating proper, central utility classes and interfaces.
  • Generators will rarely fail now, generally only throwing upon IO exceptions.
  • Proper logging is now used across the project, with an important guideline: error logs must only be used for errors that result in the mappings being unusable within Geyser.
    • This guideline makes it easy to recognise failures, as error logs are highlighted in red by default.

The root package (org.geysermc.mappings)

The root package contains the core classes of the generator, used all across the codebase.

FileType

A FileType stores a (relative) path to a file, its codec, and its file type (JSON, NBT, or plain text). FileTypes are constants and defined in the FileType record itself. Every file touched by the generator (including files not generated by it, such as palette files) has a FileType 1.

MappingsAccess

An implementation of the MappingsAccess interface represents access to the mappings folder (NOT the submodule). This interface is a functional one, and has many default methods for reading and writing FileTypes.

MappingsGenerator, the abstract base class for all generators, implements MappingsAccess, allowing the generators to easily access the mappings folder with its utility methods.

MappingsGenerators

MappingsGenerators is the project's DataGeneratorEntrypoint.

MappingsOutput

MappingsOutput implements Mojang's CachedOutput, and builds further upon it: the class manages the file_hashes.json file, a JSON file containing the hashes of all the files generated by the generators, which is committed to VCS. Using the hashes in this file, MappingsOutput is able to generate a "files changed" report, which is shown at the end of the generation process.

This class also manages deleting old files, which is normally done by CachedOutput, however, this would also delete files not generated by the current subset of generators, which is not wanted behaviour.

MappingsOutput is automatically used for all generators, which is done using mixins.

The definitions package

The definitions package holds many data records with codecs, used for reading and writing to files, and building mappings. These records are grouped in packages by the generator(s) that need them.

The generator package

The generator package holds the abstract base class MappingsGenerator, which implements MappingsAccess and Mojang's DataProvider. The package also holds every generator (which all extend the base MappingsGenerator). These classes generally aren't too long, as the code to generate mappings is also shared with the definitions in the definitions package, and the renamers in the names package.

Generators are further grouped into the javaclass package for Geyser's Java class generators, and the mcpl package for MCPL's generators.

The names package

The names package contains hardcoded Java to bedrock renames, used in the generators. These renames are stored in "renamers".

The base renamer is the InstanceRenamer functional interface, which functions like the old "block state name override" system: implementations take a type T (e.g. Block), and return a function turning an instance of type T (I, e.g. BlockState) into the renamed result (R, usually String or Identifier). The TypeRenamer functional interface extends on this and is used for instance-independent renames (i.e. T -> R directly). Both InstanceRenamer and TypeRenamer have helper methods and builders for creating renamers.

Renamers are kept in the Renamers class. For renamers with little code, e.g. Renamers.BIOMES, the code is kept in the Renamers class itself. For more complicated renamers, the code is kept in a separate class in the renamers child package, with a reference in the Renamers class.

Other packages

Mixins are kept in the mixin package. As mixins can be complicated to understand, each mixin must have a Javadoc explaining its purpose. Furthermore, the resources package contains classes for automatically downloading and managing resources (for now, only bedrock-samples.zip). Lastly, the util package contains utility classes, such as FieldConstructor, MappingsUtil, and MappingsCodecs.

Generator specific changes

To be described...

Changes to the generated mappings

  • The additional_offhand_items.json file is now tracked in the mappings submodule.
  • Objects in JSON files are now sorted according to Mojang's key comparing order (type and parent keys at the top, then sort alphabetically).
  • Compound tags in NBT files are now sorted similarly to objects in JSON files.
  • The interactions.json file now holds the DataVersion for which it was generated, which allows skipping the generator when the data version hasn't changed.
  • The sounds.json file has been cleaned up (empty string mappings have been removed).
  • Most of the other differences are results from indentation, line endings, or sorting of contents.

TO-DOs:

  • Clean up AWs
  • Block shapes generator
  • check library versions in libs.versions.toml
  • Javadocs
  • README instructions (including on how to add new providers)
  • Ability to select providers
  • networkCodec changes fix
  • Automatically download palette
  • Automatically clonesubmodule
  • Biome mappings generator slow
  • General code clean up
  • Test line endings on windows
  • Finish documenting generator-specific changes in PR description
  • Test generated mappings in Geyser, test generated classes in MCPL
  • 26.2

Footnotes

  1. The only exception to this is the bedrock-samples.zip file.

…enamer to reduce code duplication for renames
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant