Development Guide¶
This guide covers everything you need to set up a development environment, build the mod, run tests, and work with the multi-version build system.
See also: Contributing for the contribution workflow, Guidelines for code style and conventions.
Prerequisites¶
| Requirement | Version | Notes |
|---|---|---|
| Java | 17 | Required — Minecraft 1.20.1 targets Java 17 (Mojang moved to Java 17 as the minimum starting with 1.18), and the project uses Java 17 language features (records, sealed classes) |
| Git | 2.x+ | For version control and conventional commits |
| IDE | Any | IntelliJ IDEA recommended (free Community edition works) |
| git-cliff | Latest | Changelog generation for releases — winget install git-cliff or git-cliff.org |
Note: You do not need to install Gradle — the project includes the Gradle Wrapper (
gradlew/gradlew.bat).
Getting Started¶
Clone and Build¶
# Clone the repository
git clone https://gitlab.com/starshadow/games/minecraft/minecraft-ansible-crafting.git
cd minecraft-ansible-crafting
# Build the mod (includes git SHA in version for dev builds)
# Linux/macOS
./gradlew build
# Windows
gradlew.bat build
Run the Development Client¶
This launches a Minecraft client with the mod loaded. Hot-swap is supported for minor code changes if your IDE is configured for it.
Run the Development Server¶
Build Types¶
flowchart LR
DEV["./gradlew build"] -->|"includes git SHA"| DEV_JAR["ansiblecrafting-0.1.0+abc1234.jar"]
REL["./gradlew build -Prelease"] -->|"clean version"| REL_JAR["ansiblecrafting-0.1.0.jar"]
| Build Type | Command | Version Format | Use Case |
|---|---|---|---|
| Development | ./gradlew build |
0.1.0+abc1234 |
Local testing, CI builds |
| Release | ./gradlew build -Prelease |
0.1.0 |
Distribution, mod platforms |
Gradle Task Reference¶
| Task | Description | Example |
|---|---|---|
build |
Compile and create the mod JAR | ./gradlew build |
test |
Run JUnit 5 unit tests | ./gradlew test |
spotlessCheck |
Check code formatting (fails on violations) | ./gradlew spotlessCheck |
spotlessApply |
Auto-fix code formatting | ./gradlew spotlessApply |
runClient |
Launch Minecraft client with the mod | ./gradlew runClient |
runServer |
Launch Minecraft server with the mod | ./gradlew runServer |
clean |
Delete all build artifacts | ./gradlew clean |
buildAllVersions |
Build for all Stonecutter-configured MC versions | ./gradlew buildAllVersions |
Recommended Pre-Commit Workflow¶
# Format code, then build and test in one command
./gradlew spotlessApply build --no-configuration-cache
The --no-configuration-cache flag is needed because Stonecutter and configuration caching can conflict.
Git Hooks (Optional but Recommended)¶
The project includes git hooks in .githooks/ that automatically enforce formatting and commit message conventions:
| Hook | What It Does |
|---|---|
pre-commit |
Runs spotlessCheck on staged Java files — blocks commits with formatting violations |
commit-msg |
Validates that commit messages follow Conventional Commits format |
To enable the hooks:
To disable them later:
Note: The hooks are opt-in. CI will still catch formatting and commit message issues even without local hooks.
Code Formatting¶
The project uses Spotless with Palantir Java Format for consistent code style.
Key rules:
- Tabs for Java indentation, 4 spaces for Gradle
- 120-character line length
- Import order: java.* → javax.* → net.minecraft.* → net.fabricmc.* → com.ansiblecrafting.* → everything else
# Check formatting (CI will fail if this fails)
./gradlew spotlessCheck
# Auto-fix formatting
./gradlew spotlessApply
Always run
spotlessApplybefore committing. The CI pipeline runsspotlessCheckand will reject improperly formatted code.
Testing¶
The project uses JUnit 5 for unit tests. Tests live in src/test/java/ and mirror the main source structure.
Running Tests¶
# Run all tests
./gradlew test
# Run a specific test class
./gradlew test --tests "com.ansiblecrafting.config.ModConfigTest"
# Run with verbose output
./gradlew test --info
Test Structure¶
src/test/java/com/ansiblecrafting/
├── config/
│ └── ModConfigTest.java # 46 tests — config loading, validation, defaults
├── crafting/
│ └── CraftingSessionManagerTest.java # 12 tests — session lifecycle
└── inventory/
└── ... # Inventory scanning tests
Writing Tests¶
Follow the AAA pattern (Arrange, Act, Assert) and descriptive naming:
@Test
@DisplayName("scanRange clamps to minimum of 1 when set to 0")
void scanRange_setToZero_clampsToOne() {
// Arrange
ModConfig config = new ModConfig();
// Act
config.setScanRange(0);
// Assert
assertEquals(1, config.getScanRange());
}
See Guidelines — Testing for full conventions.
Multi-Version Support (Stonecutter)¶
The project uses Stonecutter to support multiple Minecraft versions from a single codebase.
How It Works¶
flowchart TD
SRC["src/main/java/<br/>Shared source code"] --> SC["Stonecutter<br/>Preprocessor"]
SC -->|"MC 1.20.1"| V1["versions/1.20.1/<br/>Version-specific overrides"]
SC -->|"MC 1.20.2+"| V2["versions/1.20.2/<br/>Version-specific overrides"]
V1 --> JAR1["ansiblecrafting-*-mc1.20.1.jar"]
V2 --> JAR2["ansiblecrafting-*-mc1.20.2.jar"]
Conditional Compilation¶
Use Stonecutter comment markers for version-specific code:
/*? if >=1.20.2 {*/
// Code for Minecraft 1.20.2 and above
/*?} else {*/
// Code for Minecraft 1.20.1 and below
/*?}*/
Version-Specific Resources¶
Version-specific resource overrides go in versions/<mc-version>/src/main/resources/. These override files in the main src/main/resources/ directory.
Building All Versions¶
This produces JARs for every configured Minecraft version.
Project Structure¶
ansible-crafting/
├── src/main/java/com/ansiblecrafting/
│ ├── AnsibleCraftingMod.java # Main mod entry point
│ ├── client/ui/ # UI components (panels, widgets)
│ ├── config/ # ModConfig, Cloth Config integration
│ ├── crafting/ # CraftingSession, CraftingSessionManager
│ ├── integration/ # Recipe viewer integrations
│ │ ├── emi/ # EMI plugin
│ │ └── rei/ # REI plugin
│ ├── inventory/ # InventoryScanner, AggregatedInventory
│ ├── mixin/ # Server-side mixins
│ │ └── client/ # Client-side mixins
│ └── network/ # Client-server packet definitions
├── src/main/resources/
│ ├── assets/ansiblecrafting/ # Textures, lang files
│ ├── fabric.mod.json # Fabric mod metadata
│ └── ansiblecrafting.mixins.json # Mixin configuration
├── src/test/java/com/ansiblecrafting/ # Unit tests
├── versions/ # Stonecutter version overrides
├── scripts/ # Release scripts, splash taglines
├── docs/ # Technical documentation
├── build.gradle # Build configuration
├── gradle.properties # Mod metadata and dependency versions
├── stonecutter.gradle # Multi-version build config
└── cliff.toml # git-cliff changelog config
For a deeper dive into the architecture, see Architecture Overview.
Recipe Viewer Development¶
The mod integrates with both EMI and REI. You can switch which recipe viewer loads in the dev environment by editing gradle.properties:
Set to emi, rei, or none and re-run ./gradlew runClient.
Debug Logging¶
For detailed runtime logging during development, see the Debug Logging Guide.