Building AuthCore for every version (1.16.x - 26.1-26.3)
Minecraft changed the rules at 26.1: Mojang released the game unobfuscated (readable Mojang names in the shipped jar, parameter names included) and Fabric's intermediary no longer exists for that era. The Fabric project announced that yarn is discontinued and mods must migrate to Mojang names.
That is why AuthCore ships one jar per version range and loader, 7 jars (3 ranges ×
Fabric/Forge/NeoForge), all built from the same source tree (src/main/java, Mojang
names everywhere):
| Jar | Built at | Loader | Names | Minecraft | Java level |
|---|---|---|---|---|---|
authcore-1.16-1.18-fabric-<v>.jar |
1.18.2 | Fabric | Mojang (mojmap) | 1.16.0 - 1.18.2 | 17 |
authcore-1.16-1.18-forge-<v>.jar |
1.18.2 | Forge | Mojang (mojmap) | 1.16.0 - 1.18.2 | 17 |
authcore-1.19-1.21-fabric-<v>.jar |
1.21.11 | Fabric | Mojang (mojmap) | 1.19.0 - 1.21.11 | 21 |
authcore-1.19-1.21-forge-<v>.jar |
1.21.11 | Forge | Mojang (mojmap) | 1.19.0 - 1.21.11 | 21 |
authcore-1.19-1.21-neoforge-<v>.jar |
1.21.11 | NeoForge | Mojang (mojmap) | 1.19.0 - 1.21.11 | 21 |
authcore-26.1-26.3-fabric-<v>.jar |
26.3 | Fabric | Mojang (unobfuscated) | 26.1 - 26.3 | 25 |
authcore-26.1-26.3-neoforge-<v>.jar |
26.3 | NeoForge | Mojang (unobfuscated) | 26.1 - 26.3 | 25 |
Mappings are Mojang (mojmap) for every line, the old yarn line is gone. The 26.1-26.3 jar ships unobfuscated (Mojang names in the game jar itself, so no remap is needed), while the 1.16-1.21 jars are remapped to intermediary for the game runtime. Because the game uses either intermediary (≤1.21.11) or Mojang names (≥26.1), the two name-spaces cannot coexist in one compiled jar, installing the right jar per server version is expected behaviour for every mod today.
🧩 Bonus: each jar also acts as a BungeeCord / Velocity plugin (
bungee.yml+velocity-plugin.json+in.potenfyr.authcore.proxy.*). The proxy role is version-independent, so it is compiled once insrc/main/javaand lands in every jar, drop any jar into a proxy'splugins/folder and it auto-detects (config:config/authcore-proxy.properties).
Source layout
src/
├── fabric/ fabric entrypoint (FabricEntry.java)
├── neoforge/ neoforge entrypoint (NeoForgeEntry.java)
└── main/ ACTIVE merged tree - server mod + proxy plugin in ONE jar
├── java/ all code (Mojang names; version-specific code gated by Stonecutter
│ conditionals, e.g. /*? if < 26 {*/; forge entrypoints included)
└── resources/ fabric.mod.json + mods.toml + neoforge.mods.toml + mixin configs
+ bungee.yml + velocity-plugin.json + assets (lang files, icon)
Building
The build is a Stonecraft 1.14 + Stonecutter 0.9 workspace: settings.gradle.kts
registers one variant per (Minecraft, loader), :1.18.2-fabric, :1.18.2-forge,
:1.21.11-fabric, :1.21.11-forge, :1.21.11-neoforge, :26.3-fabric, :26.3-neoforge
(the active version is 1.21.11-fabric), all configured by the central
build.gradle.kts (Kotlin DSL). Per-version game/loader dependencies live in
versions/dependencies/<mc>.properties.
# Default build - the active Stonecutter version (1.21.11-fabric):
./gradlew build
# -> versions/1.21.11-fabric/build/libs/authcore-1.19-1.21-fabric-1.0.0.jar
# Every variant at once (Stonecutter chiseled build - all seven jars):
./gradlew chiseledBuild
# One specific variant:
./gradlew :26.3-fabric:build
# -> versions/26.3-fabric/build/libs/authcore-26.1-26.3-fabric-1.0.0.jar
./gradlew :26.3-neoforge:build
# -> versions/26.3-neoforge/build/libs/authcore-26.1-26.3-neoforge-1.0.0.jar
./gradlew :1.21.11-forge:build
# -> versions/1.21.11-forge/build/libs/authcore-1.19-1.21-forge-1.0.0.jar
# Collect a built jar into the root build/libs (release pipeline / harness):
./gradlew :1.18.2-fabric:collectJars
Missing JDK toolchains are auto-downloaded by the foojay resolver (17 for the 1.16-1.18 group, 21 for 1.19-1.21, 25 for 26.1-26.3).
Version-specific code (Stonecutter conditionals)
There is one source tree, no more mirrored classic / modern copies. Version-specific
code is gated inline with Stonecutter preprocessor comments, e.g. the inventory mixins use
ClickType below 26 and the 26.1-26.3 ContainerInput API above:
/*? if < 26 {*/
actionType == ClickType.THROW
/*?} else {*/
actionType == ContainerInput.THROW
/*?}*/
- Loader conditionals are registered automatically by Stonecraft:
fabric,forge,neoforge,forgeLike. - 26.1-26.3 API differences already handled via conditionals:
displayClientMessage(Component, boolean)→sendSystemMessage(Component, boolean)ClickType→ContainerInput(same constants)
How to find 26.3 API ground truth
The 26.3 game jar is unobfuscated, so javap gives exact answers, point it at the 26.3
merged game jar from the Gradle cache:
javap -cp <path-to-26.3-minecraft-merged.jar> \
net.minecraft.client.gui.screens.Screen
Verified on real servers
test/docker boots real Fabric / Forge / NeoForge servers in Docker - on the official
eclipse-temurin JRE images (17/21/25, one per version group), running the whole matrix in
parallel on every range endpoint. It checks that each jar actually works (clean mod load with no
errors/warnings, banner shows the correct version/MC/security summary, config files created,
/authcore console commands succeed). The range-group matrix:
| Group | Jars (built at) | Loaders | Verify endpoints | JBR |
|---|---|---|---|---|
| G1 | authcore-1.16-1.18-* (1.18.2) |
fabric, forge | 1.16.5, 1.17.1, 1.18.2 | 17 |
| G2 | authcore-1.19-1.21-* (1.21.11) |
fabric, forge, neoforge | 1.19.4, 1.20.6, 1.21.1, 1.21.11 | 21 |
| G3 | authcore-26.1-26.3-* (26.3) |
fabric, neoforge | 26.1.2, 26.2, 26.3 | 25 |
Verified matrix (2026-08-29): every loader build target boots clean on its range
endpoints - fabric 1.18.2 / 1.19.4 / 1.20.6 / 1.21.1 / 1.21.11 / 26.1.2 / 26.2 / 26.3,
forge 1.21.11, neoforge 1.21.11 / 26.1.2 / 26.2 / 26.3 - zero errors and zero warnings.
Older endpoints (fabric 1.16.5/1.17.1 provisioning, forge 1.19.4-1.21.1,
neoforge 1.20.6/1.21.1) are being brought to full green; future lines (27+) get an
open-ended <version>+ range jar automatically.
Run it yourself (requires only Docker):
test/build.sh # build all 7 variants in Docker (temurin, no local JDK needed)
test/docker/run-tests.sh # smoke: boot each build target (parallel)
test/docker/run-tests.sh --all # full range-endpoint matrix
Options: --all / --smoke / --groups <ranges> / --loaders <names> / --versions <mc> / --jar <path> /
--parallel <n> / --timeout <sec>.
The harness caches server downloads between runs and
writes test/docker/report/.