Module metadata, such as the main module class, is contained in the META-INF/librarianlib/modules/<module id>.json file:
{
"mainClass": "com.teamwizardry.librarianlib.<module id>.Lib<Module Name>Module"
}Each module includes a skeleton mod. This mod exists largely to allow core mods to be loaded when the modules are
separate. The modules themselves are actually loaded by the core module's bootstrapper, not by the skeleton mod, so
modules should assume their mod ID is librarianlib. For every module except the core module, the gradle script
automatically generates each module's skeleton class, mixin connector, mods.toml file, and pack.mcmeta file during
the build process.
Test mods are each separate mods with the mod ID librarianlib-<module id>-test, primarily to avoid item/block ID
conflicts, and have their mods.toml file generated at compile time, similarly to the module skeleton mods. Because
they register blocks and items, test mods need to be loaded by Forge, not the core module, so the modules themselves
should have the @Mod annotation. The test mods load only after all the modules have loaded.
Dependencies on other mods should be added to the META-INF/dependencies.toml file in each module. The contents of this
file will be appended to the core bootstrapper's mods.toml file. The actual mod jars should be added to the mod
dependency configuration. Any artifacts in this configuration will be copied into the runtime mods directory.
Non-mod libraries should be added to the shade dependency configuration, which also adds them to the api
configuration. Anything not provided by another mod must be shaded in order to function. These libraries will be
shaded into the module build output at runtime since loading libraries from the root classloader can lead to
classloading issues. Every shaded package must also be added to the list of packages to
relocate by passing them to the shadePackages function. When adding or updating a shaded library, make sure to check
what transitive dependencies it has and exclude
any that aren't needed. For example, a library that depends on the Kotlin stdlib will try to shade the entire stdlib,
which is already being provided by Kottle.
Relocation rules are applied globally, so it's important to verify that the relocated packages aren't used from
Minecraft elsewhere. For example, if Minecraft includes library X and module A shades its own copy of X, then
when an unrelated module B refers to Minecraft's copy of library X, the references wind up pointing to ll.X,
which is missing at runtime when module A isn't present.
The rationale behind shading at runtime was an issue that occurred when using the fat Kottle jar (as opposed to the slim jar, which doesn't include the kotlin runtime):
For example, if a mod such as Kottle is placed on the classpath, it'll get lifted into the mod classloader. Then, when mods use Kotlin types they'll reference the Kottle classes in the mod classloader, but when non-mod libraries in the root classloader use Kotlin types they'll reference the Kottle classes that are still in the root classloader. Moving Kottle out of the root classloader avoids the duplicates, but now the libraries that are still stuck down there can't access Kotlin types. Thus, we shade all the dependencies into the runtime environment.
After switching to the slim Kottle jar that should no longer be an issue, however the runtime shading will hopefully avoid similar issues in the future, and I've spent over a week working on this gradle setup, so I really don't feel like ripping it back out again.
Additional Maven repositories must be added to the allprojects block in the root build.gradle, since all the
projects need to be able to resolve them.
There are a number of files located in the META-INF directory, and where possible, to avoid conflicts, these are
located in the META-INF/ll/<module id> directory.
Core mods for modules are defined as usual, except that the transformer names should be prefixed with <module id>.,
and the transformer javascript files should be placed in META-INF/ll/<module id>/asm/ to prevent potential
conflicts. Due to the jar merging process, the coremods.json file must have the braces ({}) on their own lines.
Each module's mixin JSON files should be placed in the META-INF/ll/<module id>/mixin/ directory. The contents of this
directory will automatically be scanned and added to the generated mixin connector.
https://github.com/bintray/gradle-bintray-plugin
- Set up the release:
- Bump the version in
gradle.properties - Run
./gradlew clean buildto verify the project builds correctly - Create a new commit with only that change, with the message
Publish v<version> - Create a new tag named
v<version>on that commit - Push to GitHub
- Bump the version in
- Create the GitHub release:
- Go to the tag list
- Click the tag you just created
- Click
Edit tag - Add the deobf, source, and obf jars from the root
build/libsdirectory (you did just run the build, right?) - Click on
Publish release
- Publishing to Bintray:
- Wait for the release action on GitHub to finish
- Sign in on Bintray
- Select the
teamwizardryrepository - It will say there are unpublished files. Click
Publish all
- TODO: CurseForge
In order for new modules to be put on JCenter, log into bintray and navigate to the newly created project. Select the
Actions dropdown in the top-right and click Add to JCenter. Select Is pom project, but don't select to add it to
OJO, since the snapshots will likely have already been uploaded and this will result in an error.
Snapshots are automatically created when pushing to any branch that starts with 1.15.
https://github.com/Kotlin/binary-compatibility-validator
Nail down publishing to jfrog and then applying for oss.jfrog.org
Fix race condition in build script (downloadMcpConfig occasionally fails, saying Cannot get property 'outputs' on null object)
