Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces support for using module descriptors in mods, as well as adding built-in module declarations for FML projects. It aims to push support for modules in the neo ecosystem forward and provide better IDE integration for modular projects.
Motivation
Starting with minecraft 1.17, Forge started using the java module system for handling game launch and modloading. This brough many positive changes to the toolchain backend. A good example is the simplified classloader hierarchy, which effectively eliminates "classloader hell", as each module is now assigned a classloader and its classes won't ever be loaded by other ones.
However, for a long time now, mods were not given the option to take advantage of modules. By adding a module declaration to their mods, modders could benefit from great features offered by the module system, including:
Goals
Non-goals
Modular Mods
If a module descriptor file exists in a mod, FML will prefer using it over generating a descriptor at runtime. However, a few adjustments must be made to the provided descriptor before it can be used.
If a mod does not include a descriptor, we fall back to the old module generation logic. In addition, modders can now provide their own module name via the
Automatic-Module-Name
manifest attribute.Version
We set the module's version to use the one provided by mod metadata, in order to keep it the same in all places and avoid possible confusion. This is needed in cases where the java compiler does not bake a version into the module during compilation.
Benefits for modders
Module goodness!
Modders gain access to great features of the java module system, including:
IDE Syntax Highlighting
Given that neo already uses modules at runtime, module encapsulation is enforced. Mods might accidentally use classes from libraries that are not exported without getting warned by the IDE. If a mod / project doesn't contain a module declaration, the IDE will treat it as a classpath library, ignoring any module information of dependencies. This can lead to unexpected crashes at runtime and needless confusion for modders.
By adding a module descriptor to our project, we enable all access-related checks (both for the IDE and compiler), eliminating possible
IllegalAccessError
s.Module declarations for FML projects
Adds compile-time module declarations for all FML projects. For now, all modules are declared
open
and export all their packages. This allows for an easier transition period without breaking dependents, should we want to encapsulate these modules in the future.The module naming conventions follows the scheme of
net.neoforged.fancymodloader.<project name>
. In total, 7 modules are being added:net.neoforged.fancymodloader.core
net.neoforged.fancymodloader.earlydisplay
net.neoforged.fancymodloader.events
net.neoforged.fancymodloader.language.java
net.neoforged.fancymodloader.language.lowcode
net.neoforged.fancymodloader.language.minecraft
net.neoforged.fancymodloader.loader
Questions and alternatives
Should we keep all FML modules open?
Currently, people are allowed reflective access into FML. I think it's a good idea to keep FML modules open even after adding declaration files during a short transition period window.
Should provided mod descriptors be forced open?
FML requires reflective access into mods, and other neo libraries (such as eventbus) might need it as well. We can open mod modules to only our own libraries, keeping them "protected" from reflective access from other mods. Alternatively, we can flag entire mod modules as open.