26.x Builds

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 in src/main/java and lands in every jar, drop any jar into a proxy's plugins/ 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)
    • ClickTypeContainerInput (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/.