# Contributing to CustomSkinLoader Universal Thanks for helping improve CustomSkinLoader. This branch is the Universal generation: one installable Bootstrap jar carries the shared Common runtime, remaps it for the active Minecraft mapping namespace, and applies loader-specific patches at launch time. A successful Java compile is useful, but changes that touch runtime loading, mappings, or transformers also need in-game verification. ## Requirements - Git. - A Java 25 JDK. Set `JAVA_HOME` if Java 25 is not the default `java` on your `PATH`. - The Gradle wrapper from this repository. - Local Minecraft test instances for the loaders and versions affected by your change. The build uses Java 25 tooling, while project sources are compiled for Java 8 compatibility unless a module explicitly provides multi-release sources such as `Common/src/main/java21`. ## Build Use the wrapper instead of a system Gradle installation. Windows: ```powershell .\gradlew.bat clean build --stacktrace ``` Linux/macOS: ```bash ./gradlew clean build --stacktrace ``` The user-facing mod artifact is: ```text Bootstrap/build/libs/CustomSkinLoader_Universal-.jar ``` `Common/build/libs/Common-.jar` is bundled into the Universal jar as `META-INF/jar-jar/CustomSkinLoader-Common.jar`. Do not publish or ask users to install the Common jar directly. ## Project Layout - `Common`: shared CustomSkinLoader runtime, configuration, skin API loaders, cache, logging, and texture utilities. - `Common/src/main/java21`: Java 21+ multi-release overrides for runtime behavior that benefits from newer JVM APIs. - `Bootstrap`: assembles the installable Universal jar. - `Bootstrap/Core`: runtime installer, remapper, mapping reader, transformer registry, and shared patch logic. - `Bootstrap/FabricV1`: Fabric and Quilt-compatible bootstrap integration. - `Bootstrap/ForgeV1`: legacy Forge coremod bootstrap. - `Bootstrap/ForgeV2`: Forge ModLauncher bootstrap. - `Bootstrap/NeoForgeV1` and `Bootstrap/NeoForgeV2`: NeoForge discovery and transformation bootstrap. - `Dummy/Bootstrap` and `Dummy/Common`: compile-time stubs for Minecraft and loader APIs. Keep these minimal; they are not runtime implementations. - `buildSrc`: local Gradle plugin code, including manifest library resolution from launcher metadata. - `.github/workflows` and `.github/scripts`: CI, release, metadata, and publishing automation. ## Development Guidelines - Keep changes scoped to the loader, mapping range, API loader, or Common behavior being modified. - Preserve compatibility across the supported Minecraft and loader matrix unless the change is intentionally narrowing support. - Prefer small, explicit compatibility branches over broad reflection or version checks when the affected API surface is known. - Treat `Bootstrap/Core/src/main/resources/customskinloader/mapping.xml` and transformer patches as runtime-critical code. Document why a mapping range or target class changed. - Do not edit generated Gradle output under `build/`, `.gradle/`, IDE metadata, or files generated by a local Minecraft test run. - Keep `Dummy` classes limited to the members needed for compilation. Runtime behavior belongs in `Common` or `Bootstrap`, not in stubs. - Update `README.md`, issue templates, or release metadata when a user-visible feature, supported loader, supported version, or install path changes. - Follow the existing Java style in nearby files. The codebase intentionally avoids adding large abstractions where a focused compatibility patch is clearer. ## Testing Checklist Before opening a pull request, run the relevant parts of this checklist: 1. Run `.\gradlew.bat clean build --stacktrace` on Windows, or `./gradlew clean build --stacktrace` on Linux/macOS. 2. Install only `Bootstrap/build/libs/CustomSkinLoader_Universal-.jar` into a clean Minecraft instance. 3. If you changed `Common`, confirm the runtime payload is regenerated under `.minecraft/CustomSkinLoader/Core/CustomSkinLoader-Common.jar`. 4. If you changed `Bootstrap`, mappings, service descriptors, or transformer patches, test at least one Forge or NeoForge instance and one Fabric or Quilt-compatible instance. 5. If you changed a version range or mapping entry, test the oldest and newest Minecraft versions covered by that range. 6. Check `.minecraft/CustomSkinLoader/CustomSkinLoader.log` for loader, remapper, transformer, and skin loading errors. 7. For skin API, cache, or network changes, test a normal online profile and a cache/local-profile fallback path when possible. There is currently no standalone test suite that replaces in-game compatibility testing. ## Pull Requests Please include: - A short summary of the behavior change. - The Minecraft versions and loaders you tested. - Any relevant `CustomSkinLoader.log` snippets for bootstrap, remapping, or skin loading issues. - Screenshots or reproduction steps for visible texture/rendering fixes. - Notes about compatibility risk when changing mappings, ASM patches, service descriptors, or build packaging. Keep pull requests focused. If a cleanup is unrelated to the bug or feature, send it separately so compatibility regressions are easier to review. ## CI and Publishing Pull requests run the shared GitHub Actions build on `windows-latest` with PowerShell and Java 25. This is a CI choice; local builds should remain portable across Windows, Linux, and macOS. Publishing jobs generate the Universal jar plus metadata files from `gradle.properties`. Beta builds publish moving beta metadata, release builds publish release metadata and upload to distribution platforms. Object-storage upload is optional and is skipped when the required secrets are not configured. To generate publish metadata locally without uploading, first build the project, then run: ```powershell .\.github\scripts\publish-artifacts.ps1 -Channel Beta -LatestJsonName latest-beta.json -DetailJsonName detail-beta.json -SkipObjectStorage ``` ## License By contributing, you agree that your contribution will be distributed under the repository license. Source code is licensed under GPL-3.0-only; see `LICENSE`.