Skip to content

Multi-version builds via Stonecutter + concurrent launch tests for every supported Minecraft version#23

Open
dsnsgithub wants to merge 10 commits into
mainfrom
multi-version-launch-tests
Open

Multi-version builds via Stonecutter + concurrent launch tests for every supported Minecraft version#23
dsnsgithub wants to merge 10 commits into
mainfrom
multi-version-launch-tests

Conversation

@dsnsgithub

Copy link
Copy Markdown
Owner

Summary

Turns the repo into a multi-version Stonecutter build (four variants covering 1.21–1.21.5, 1.21.6–1.21.11, 26.1.x, and 26.2) and extends the production client launch test from #22 to run on every supported Minecraft version concurrently in CI — 16 launch jobs, each booting a real production Fabric client under XVFB with the covering variant's built jar, entering a survival singleplayer world with the HUD active, screenshotting it, and failing on any crash.

Build

  • Stonecutter variants 1.21, 1.21.6, 26.1, 26.2, each with its own versions/<v>/gradle.properties (MC/loader/Java/fabric-api/modmenu/cloth versions and fabric.mod.json ranges)
  • 1.21.x variants build with fabric-loom-remap (intermediary, Java 21); 26.x variants with fabric-loom (Mojang names native, Java 25)
  • CI builds all four variants in parallel and uploads each jar

Launch tests

  • New launchtest/ Gradle subproject: Loom's ClientProductionRunTask can only launch the project's own Minecraft version, so this sourceless harness applies Loom with -PtestMcVersion=<version> as its MC version and launches the matching variant's jar (./gradlew :launchtest:runProductionClientGameTest -PtestMcVersion=1.21.3)
  • Its runtimeMatrix pins, per runtime version, the newest Fabric API / Mod Menu / Cloth Config whose fabric.mod.json actually accepts that version (verified against each jar's declared depends range)
  • Test driver per version family:
    • 26.x: the client gametest from feat: launch a Minecraft client in CI to verify the mod works in-game #22 (src/gametest, gametest API 5.x) unchanged
    • 1.21.4–1.21.11: a copy with the 4.x API naming (getClientWorld() instead of getClientLevel())
    • 1.21–1.21.3: no client gametest API exists — a fallback mod joins a world pre-generated by that exact version's dedicated server (.github/scripts/generate-test-world.sh) via --quickPlaySingleplayer, screenshots it, and exits cleanly

Screenshot report

  • A final job collects every version's screenshots, publishes them to the ci-screenshots branch, and embeds the full 16-version grid in a PR comment (kept up to date per push) and in the workflow job summary

Verification

This exact commit already ran green end-to-end: all 4 builds, all 16 launch tests, and the screenshot report (run #181). The fresh run on this branch will post the screenshot grid as a comment here once it finishes.

🤖 Generated with Claude Code

https://claude.ai/code/session_016TdZ9ujK7PCyCmHz6b2P4i


Generated by Claude Code

cursoragent and others added 9 commits May 8, 2026 01:06
Migrates the mod from 3 separate branches (main 26.1, support/1.21-1.21.5,
support/1.21.6-1.21.11) to a single source tree using Stonecutter 0.9.3.

- All variants now use Mojang official mappings (yarn sources for the support
  branches were converted with loom's migrateMappings task).
- Per-version gradle.properties under versions/ pin MC, fabric-api, modmenu,
  cloth-config, loader, and target Java version.
- Single root build.gradle uses stonecutter.eval(...) to switch between
  fabric-loom (26.1, unobfuscated) and fabric-loom-remap (1.21.x, obfuscated).
- Source files use //? if mc directives where the API genuinely differs:
  HudElementRegistry vs HudRenderCallback, Identifier vs ResourceLocation,
  GuiGraphicsExtractor vs GuiGraphics, drawContext.text vs .drawString,
  Holder vs Optional<ResourceKey> in Biome lookup, FPS via accessor mixin
  on 1.21.x.

The active VCS variant is 26.1 so 'git diff main' stays small.

Co-authored-by: Dominic Seung <dominic@seung.dev>
- Stonecutter uses '//? if >=1.21.6 {' (no 'mc' keyword, no quotes around
  versions) - my previous '//? if mc >= "..." {' format was rejected by the
  parser.
- client.getFps() is public on all Mojang-mapped variants (1.21, 1.21.6+,
  26.1), so the MinecraftClientAccessor mixin was redundant. Drop it and the
  empty mixin/ package; betterhud.mixins.json keeps an empty client array via
  expansion.
- Earlier I'd assumed 26.1 used getDebugHud()/hudHidden (yarn-like) names,
  but main 26.1 already uses getDebugOverlay()/hideGui (true Mojang) - same
  as the 1.21.x Mojang-migrated source. Removed the bogus directives that
  swapped between them.

After these fixes, all three variants build successfully:
  ./gradlew build
    -> versions/1.21/build/libs/betterhud-2.1.0+mc1.21.jar
    -> versions/1.21.6/build/libs/betterhud-2.1.0+mc1.21.6.jar
    -> versions/26.1/build/libs/betterhud-2.1.0+mc26.1.jar

CI workflow updated to a 3-way matrix (mc1.21/Java21, mc1.21.6/Java21,
mc26.1/Java25) that uploads each variant as a separate artifact.

Co-authored-by: Dominic Seung <dominic@seung.dev>
- Add four Stonecutter variants: 1.21 (1.21-1.21.5), 1.21.6 (1.21.6-1.21.11),
  26.1 (>=26.1 <26.2), 26.2 (>=26.2).
- All jars now declare fabric-api, modmenu, and cloth-config2 as hard runtime
  dependencies instead of bundling them (~47 KB jars vs ~2 MB before).
- Port 26.2 scaling (Matrix3x2fStack / PoseStack transforms, scaledElement*
  layout helpers, Scale setting) to every variant via Stonecutter directives.
- 26.2 uses client.gui.hud.isHidden(); all other variants use options.hideGui.
- Update to mod 2.1.1, loom 1.17-SNAPSHOT, Gradle 9.5.1; CI matrix covers all
  four variants.

Co-authored-by: Dominic Seung <dominic@seung.dev>
Merge origin/main into cursor/stonecutter-multiversion-b333, keeping the
Stonecutter four-variant layout while incorporating main's 26.2 changes
(scaling, required fabric-api/modmenu/cloth-config deps, gui.hud.isHidden).

Resolved conflicts in build.gradle, gradle.properties, BetterHUDGUI.java,
CustomText.java, ModSettings.java, fabric.mod.json, and removed a duplicate
createFloatSetting() introduced by the auto-merge in Setting.java.

Co-authored-by: Dominic Seung <dominic@seung.dev>
Merge origin/main; resolve build.yml conflict by keeping the four-variant
Stonecutter matrix while adopting main's on: push trigger (no pull_request).

Co-authored-by: Dominic Seung <dominic@seung.dev>
Use a single implCfg (modImplementation vs implementation) and only gate
mappings loom.officialMojangMappings() behind isLegacy.

Co-authored-by: Dominic Seung <dominic@seung.dev>
Keeps the multi-version Stonecutter build; the launch test itself is ported
to all supported Minecraft versions in the next commit. Takes main's client
gametest source (src/gametest) as-is.
Ports the production client launch test (PR #22) across the multi-version
build: 16 concurrent CI jobs each boot a real production Fabric client
(1.21-1.21.5, 1.21.6-1.21.11, 26.1-26.1.2, 26.2) with the covering
variant's built jar, enter a survival singleplayer world with the HUD
active, screenshot it, and fail on any crash.

- launchtest/: sourceless Gradle subproject applying Loom with
  -PtestMcVersion as its Minecraft version (Loom's ClientProductionRunTask
  can only launch the project's own MC version). Its runtimeMatrix pins,
  per runtime version, the newest fabric-api / Mod Menu / Cloth Config
  whose fabric.mod.json actually accepts that version (verified against
  each jar's declared depends range).
- Test driver mod, per version family:
  * 26.x uses /src/gametest from main unchanged (gametest API 5.x)
  * 1.21.4-1.21.11 uses a copy with 4.x naming (getClientWorld)
  * 1.21-1.21.3 has no client gametest API: a fallback mod joins a world
    pre-generated by that version's dedicated server (generate-test-world.sh)
    via --quickPlaySingleplayer, screenshots it, and exits
- CI: build matrix (4 variants) + launch matrix (16 versions) + a
  screenshot report job that publishes every version's survival screenshot
  to the ci-screenshots branch and embeds the full grid in a PR comment
  and the job summary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016TdZ9ujK7PCyCmHz6b2P4i
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Client launch test

The game launched and entered a survival singleplayer world with the HUD active, on every supported Minecraft version, for 3fa349e. A ❌ means that version's launch test did not produce a screenshot — check its job. Title-screen screenshots and game logs are in the run artifacts.

1.21
BetterHUD on Minecraft 1.21
1.21.1
BetterHUD on Minecraft 1.21.1
1.21.2
BetterHUD on Minecraft 1.21.2
1.21.3
BetterHUD on Minecraft 1.21.3
1.21.4
BetterHUD on Minecraft 1.21.4
1.21.5
BetterHUD on Minecraft 1.21.5
1.21.6
BetterHUD on Minecraft 1.21.6
1.21.7
BetterHUD on Minecraft 1.21.7
1.21.8
BetterHUD on Minecraft 1.21.8
1.21.9
BetterHUD on Minecraft 1.21.9
1.21.10
BetterHUD on Minecraft 1.21.10
1.21.11
BetterHUD on Minecraft 1.21.11
26.1
BetterHUD on Minecraft 26.1
26.1.1
BetterHUD on Minecraft 26.1.1
26.1.2
BetterHUD on Minecraft 26.1.2
26.2
BetterHUD on Minecraft 26.2

…load guide

- supported-versions.json now drives everything: the Stonecutter variant
  list (settings.gradle), the launch tests' per-version runtime mods, both
  CI matrices (generated by a small setup job), and the screenshot report.
  Adding a new Minecraft version is now a one-file change unless it needs
  a new build variant (documented in the README).
- New root task modrinthBundle collects the release jars into
  build/modrinth/ with UPLOAD.md listing exactly which Minecraft versions
  to select for each jar on Modrinth; CI publishes it as the
  modrinth-upload artifact on every push.
- Removed comments referencing the pre-Stonecutter layout (support/*
  branches, the old single-version main build).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016TdZ9ujK7PCyCmHz6b2P4i
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants