Building and testing
Build all three supported jars from source, run the test suite, and understand what the CI pipeline does.
Java 25 and a network connection for the Gradle toolchain are required. The repository builds a NeoForge jar and two Fabric jars from one core source tree.
Requirements
| Requirement | Value |
|---|---|
| Java | 25, set through the Gradle toolchain |
| Network | Required for the first build to fetch the toolchain and dependencies |
| Gradle | Provided by the wrapper — do not install it separately |
The build sets a Java toolchain explicitly:
java { toolchain { languageVersion = JavaLanguageVersion.of(25) } }
The two Gradle builds
The repository has two Gradle projects.
| Project | Directory | Loader | Minecraft |
|---|---|---|---|
| Root | . | NeoForge | 26.2 |
| Fabric | fabric/ | Fabric | 26.3 by default |
Both compile the same core sources. The root project adds
src/neoforge/java and one compat source set; the Fabric project adds
fabric/src/main/java and its own compat source set.
sourceSets { main { java { srcDirs = ['src/main/java', 'src/neoforge/java', 'src/compat/mc26_2/java'] } } }
Building
NeoForge, Minecraft 26.2
$ ./gradlew buildFabric, Minecraft 26.3
$ cd fabric && ./gradlew buildFabric, Minecraft 26.2
$ ./gradlew build -Pminecraft_version=26.2 "-Pminecraft_version_range=>=26.2 <26.3" -Pfabric_version=0.161.0+26.2On Windows, use gradlew.bat instead of ./gradlew.
Where the jars land
| Build | Output |
|---|---|
| NeoForge | build/libs/inputbooster-<version>-nf-mc262.jar |
| Fabric | fabric/build/libs/inputbooster-<version>-fabric-mc263.jar |
The version string comes from gradle.properties and carries the loader
flavour, for example 4.1.2-alpha-fabric or 4.1.2-alpha-nf-mc262.
Running the tests
$ cd fabric && ./gradlew testThere are 16 test classes in fabric/src/test/java/dev/inputbooster:
| Test | What it covers |
|---|---|
AdaptivePollRateTest | The auto poll rate targets, ramp and instability clamp |
ComboKeyPresetsTest | The Ctrl+1-5 preset values and the latch |
CpsLimiterTest | The token bucket |
CpsLimiterBurstTest | Burst behaviour against the bucket |
CpsLimiterModesTest | FIXED, HUMANIZED, WEAPON_AWARE and COOLDOWN |
EngineConfigTest | Engine mode resolution |
FabricDependencyRangeTest | The Fabric dependency range form |
InputActionQueueTest | The queue bound and the counter |
InputBoosterConfigTest | Config round trips and validation |
InputEngineTest | Edge detection across both sources |
LatencyProfilerTest | The rolling window and the peak |
MixinDeclarationTest | The mixin declaration rules |
MixinTargetSignatureTest | Every hook signature against the real Minecraft jar |
ProfileAndReplayTest | Profile capture, apply and replay behaviour |
SessionStatsTest | The CPS buckets and the session counters |
SuppressionAndOriginTest | The tick-scoped suppression tokens and the replay origin |
The changelog for 4.1.0-alpha records 81 tests in total.
The two tests that guard the mod
MixinDeclarationTest and MixinTargetSignatureTest exist because of two
release-stopping crashes.
MixinDeclarationTest fails the build if a registered mixin declares a
non-private static method. Mixin only permits private static helpers inside a
mixin, and a public one aborts the transformation of the whole target class.
That bug shipped in 4.0.2-stable and crashed every client before the main
menu.
MixinTargetSignatureTest checks every @Inject, @Accessor and
@Invoker against the resolved Minecraft jar, for both the 26.2 and 26.3
builds. It exists because 4.1.0-alpha crashed on every loader: the keyboard
mixin was written against the 1.21 signature keyPress(long, int, int, int, int) while 26.2 and 26.3 use keyPress(long, int, KeyEvent).
CI
The gradle.yml workflow runs on pushes to main and
fabric-26.2-26.3, on v* tags, on pull requests targeting main, and
through manual workflow dispatch.
| Job | What it does |
|---|---|
build-neoforge | Builds the NeoForge 26.2 jar on Temurin 25 |
build-fabric | Builds both Fabric jars from a matrix, then verifies the metadata |
release | Publishes a GitHub release with all three jars |
The Fabric job verifies the dependency range form before it uploads anything:
grep -q '"minecraft": *">=' /tmp/fabric.mod.json \ || { echo "minecraft dependency must use the '>=x <y' form" >&2; exit 1; }
The release job refuses to publish unless all three jars are present, derives
the tag from mod_version when there is no explicit tag, and marks a release
as a prerelease when the version contains alpha or beta.
Fabric unit tests and build matrix
The test.yml workflow
adds a dedicated Fabric test-and-build job. It runs on pushes to main and
fabric-26.2-26.3 when files under fabric/ or src/, or the workflow
itself, change. It can also be started manually from GitHub Actions.
| Matrix target | Minecraft range | Fabric API |
|---|---|---|
| Fabric 26.2 | >=26.2 <26.3 | 0.161.0+26.2 |
| Fabric 26.3 | >=26.3 <26.4 | 0.161.0+26.3 |
Each matrix job uses Temurin Java 25 and runs
./gradlew clean test build --no-daemon from fabric/, passing the
matching Minecraft version, dependency range and Fabric API version. JUnit
reports are uploaded even when a test fails; the Fabric jar is uploaded only
after a successful build. Both artifact types are retained for 14 days.
Headless client smoke test
The client-smoke.yml workflow
uses the same two-version Fabric matrix and push/path filters, and also
supports manual dispatch. It starts runClient under Xvfb with Mesa software
rendering and a null audio backend, so CI does not need a physical display or
audio device.
The check waits up to 210 seconds for the client log marker
Sound engine started, then verifies that the client remains running for
another 10 seconds. It uploads the client console, game logs and crash reports
for 14 days.
Running the mod in a development client
Both Gradle projects define a client run configuration:
./gradlew runClient
The NeoForge root project sets neoforge.enabledGameTestNamespaces to the mod
id, so game tests in that namespace run in the development client.
Related pages
- Architecture — the source layout.
- Mixin inventory — what the signature test checks.
- Versioning — how version numbers map to jars.