- Java 99.9%
| _assets | ||
| buildSrc | ||
| fabric-1.20.1 | ||
| fabric-1.21.1 | ||
| fabric-1.21.11 | ||
| floader-only | ||
| forge-1.20.1 | ||
| gradle/wrapper | ||
| lib | ||
| neo-1.21.1 | ||
| neo-1.21.11 | ||
| notes | ||
| uploader | ||
| vanilla | ||
| .gitignore | ||
| build.gradle | ||
| CHANGELOG.md | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| README.md | ||
| secrets.txt.example | ||
| settings.gradle | ||
| task.sh | ||
quat's mods (Season 2)
This monorepo contains the source for all of my Season 2 mods. They can be identified by their datestamped versions (a version number like 2025.08.10 for a mod released on August 10, 2025) and a dependency on modder_name_lib. If it has a much smaller version number, it's a Season 1 mod.
- Modder Name Lib (fabric/forge 1.20.1, fabric/neoforge 1.21.1, 1.21.11)
- Contains code shared between all of the Season 2 mods.
- You probably don't need to download it separately; on supported platforms it is shipped alongside each mod with the modloader's jar-in-jar system.
- Rebind Narrator (fabric/forge 1.20.1, fabric/neoforge 1.21.1, 1.21.11)
- Change the narrator keybind.
- Curseforge, Modrinth.
- Season 1 codebase: quat1024/RebindNarrator
- Crowmap (fabric/forge 1.20.1, fabric/neoforge 1.21.1, 1.21.11)
- Maps update anywhere in your inventory.
- Curseforge, Modrinth .
- Season 1 codebase: quat1024/Crowmap
- Packages (fabric/forge 1.20.1, fabric/neoforge 1.21.1)
- 512 items is all you need. The underpowered barrels mod.
- Curseforge, Modrinth
- Season 1 codebase: quat1024/packages
Why
I called it "project sanity". I was getting very annoyed with Minecraft modding largely because of the porting workload, the code duplication, the long wait-times when switching between projects, and the frictions involved in scaffolding a new project (even a small throwaway project). So this repo (hopefully!) allows me to work on mods without the things that burn me out.
How
It's multi-version development, multi-mod development, and multi-loader development in the same repo.
The list of mods and supported Minecraft versions for each mod is defined in vanilla/build.gradle. Some common variables can be set from there too. A version-independent source set is created for each mod (modidAny), and for each supported version a version-specific source set is created (modid1_21_1). The version-dependent set can compile against the version-independent set, and unless quatlib = false in build.gradle, it can additionally compile against the corresponding modderNameLib___ sets. Minecraft classes are provided with a builtin copy of minivan. See VanillaSetupPlugin in buildSrc.
Also in the vanilla buildscript, the intersection of all minecraft versions is supplied with crossroad. This is a little janky!
:vanilla emcompasses all code which doesn't depend on a modloader in the same Gradle subproject, specifically and only because modloader ecosystem plugins are not as flexible; you can't install two different versions of neoforge in the same gradle project (and I don't want to know what happens if you try to apply Loom as well). Those loader subprojects depend on the artifacts built in :vanilla and add more classes of their own. A modidSplat configuration contains all items from :vanilla which should be copied-and-pasted unchanged into the unmapped jar. Mapping is skipped on Neoforge because it's not needed, everything else feeds the jar through the remapping implementation provided by the ecosystem plugin, although mixin refmaps are manually compiled (again, because loader-specific gradle plugins are not flexible enough and I had to reimplement it). See AbstractLoaderSetupPlugin in buildSrc.
In the top-level build.gradle, the global version number is set based off the current date. Plugin versions are defined in buildSrc/build.gradle.
status
Wishlist:
- Add more things to the datagen system
- datagen recipes
- datagen block loot tables (at least the simple ones)
- Make moddernamelib less "special" throughout the ecosystem. E.g. i should be able to make a second quatlib for my mods on very old versions
- Switch to Neoform instead of minivan
- Cut my losses with the config system. It's overcomplicated and not going anywhere
Release process
./task.sh build(or just./gradlew clean build)- compile everything
./task.sh collect- gets the changelog + all built jars out of
whatever-1.xx.x/build/libs/, and dumps them in./collect, the staging area - stop here if you just want to build the mods locally or play with them yourself
- gets the changelog + all built jars out of
./task.sh upload(or just./gradlew :uploader:run)- publish the mods to curseforge and modrinth
- requires some publishing secrets in secrets.txt (WIP, should be thru env variables tbh...)
./task.sh mktag- create a Git tag with the current date
- push
git push && git push --tags
Also remember to update the changelogs on notes.hsa (just do that manually)