From b2045653efc5d2c3a5d144a15dab173f26a7063b Mon Sep 17 00:00:00 2001 From: Federico Leiva Date: Tue, 27 Jan 2026 17:46:48 -0300 Subject: [PATCH 1/7] Enhance build configuration and dependencies for Hytale plugin to use HytaleServer.jar from official maven repository. Added permissions in workflows to allow github action to create new releases. --- .github/workflows/build.yml | 110 ++++++++++++++------------- build.gradle | 147 ++++++++++++++++++++++-------------- gradle.properties | 7 +- 3 files changed, 155 insertions(+), 109 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 65fd529..cfbee71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,12 @@ name: Build Plugin +permissions: + contents: write + on: push: branches: [ main, develop ] + tags: [ 'v*' ] pull_request: branches: [ main ] @@ -11,62 +15,62 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup Java 25 - uses: actions/setup-java@v4 - with: - java-version: '25' - distribution: 'temurin' - - - name: Cache Gradle Dependencies - uses: actions/cache@v4 - with: - path: ~/.gradle - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - - name: Grant Execute Permission for Gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew shadowJar - - - name: Run Tests - run: ./gradlew test - - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: plugin-jar - path: build/libs/*.jar - + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 25 + uses: actions/setup-java@v4 + with: + java-version: '25' + distribution: 'temurin' + + - name: Cache Gradle Dependencies + uses: actions/cache@v4 + with: + path: ~/.gradle + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Grant Execute Permission for Gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Run Tests + run: ./gradlew test + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: plugin-jar + path: build/libs/*.jar + release: needs: build runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup Java 25 - uses: actions/setup-java@v4 - with: - java-version: '25' - distribution: 'temurin' - - - name: Grant Execute Permission for Gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew shadowJar - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - files: build/libs/*.jar - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 25 + uses: actions/setup-java@v4 + with: + java-version: '25' + distribution: 'temurin' + + - name: Grant Execute Permission for Gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: build/libs/*.jar + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle b/build.gradle index 8df6db3..2b13069 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.3' + id 'com.gradleup.shadow' version '9.3.1' } import org.gradle.internal.os.OperatingSystem @@ -26,11 +27,10 @@ ext { } } -if (!project.hasProperty('hytaleHome')) { - throw new GradleException('Your Hytale install could not be detected automatically. If you are on an unsupported platform or using a custom install location, please define the install location using the hytale_home property.'); -} -else if (!file(project.findProperty('hytaleHome')).exists()) { - throw new GradleException("Failed to find Hytale at the expected location. Please make sure you have installed the game. The expected location can be changed using the hytale_home property. Currently looking in ${project.findProperty('hytaleHome')}") +def hytaleHomePath = project.findProperty('hytaleHome') +def hasHytaleHome = hytaleHomePath && file(hytaleHomePath).exists() +if (!hasHytaleHome) { + logger.lifecycle("Hytale install not detected; run configs that launch the server will be skipped. Set -Phytale_home=/path/to/Hytale to enable them.") } java { @@ -45,16 +45,29 @@ javadoc { } // Adds the Hytale server as a build dependency, allowing you to reference and -// compile against their code. This requires you to have Hytale installed using -// the official launcher for now. +// compile against their code without bundling it. When a local install is +// present, we still use its jar for launching the server in IDE run configs. dependencies { - implementation(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar")) + compileOnly("com.hypixel.hytale:Server:$hytale_build") + if (hasHytaleHome) { + runtimeOnly(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar")) + } + implementation('org.xerial:sqlite-jdbc:3.51.1.0') + implementation('com.j256.ormlite:ormlite-jdbc:6.1') + implementation('org.postgresql:postgresql:42.7.3') + implementation('com.mysql:mysql-connector-j:9.1.0') } -// Create the working directory to run the server if it does not already exist. -def serverRunDir = file("$projectDir/run") -if (!serverRunDir.exists()) { - serverRunDir.mkdirs() +repositories { + mavenCentral() + maven { + name = "hytale-release" + url = uri("https://maven.hytale.com/release") + } + maven { + name = "hytale-pre-release" + url = uri("https://maven.hytale.com/pre-release") + } } // Updates the manifest.json file with the latest properties defined in the @@ -78,54 +91,78 @@ tasks.named('processResources') { dependsOn 'updatePluginManifest' } -def createServerRunArguments(String srcDir) { - def programParameters = '--allow-op --disable-sentry --assets="' + "${hytaleHome}/install/$patchline/package/game/latest/Assets.zip" + '"' - def modPaths = [] - if (includes_pack.toBoolean()) { - modPaths << srcDir - } - if (load_user_mods.toBoolean()) { - modPaths << "${hytaleHome}/UserData/Mods" - } - if (!modPaths.isEmpty()) { - programParameters += ' --mods="' + modPaths.join(',') + '"' - } - return programParameters +tasks.named('shadowJar') { + archiveClassifier.set('') + mergeServiceFiles() } -// Creates a run configuration in IDEA that will run the Hytale server with -// your plugin and the default assets. -idea.project.settings.runConfigurations { - 'HytaleServer'(org.jetbrains.gradle.ext.Application) { - mainClass = 'com.hypixel.hytale.Main' - moduleName = project.idea.module.name + '.main' - programParameters = createServerRunArguments(sourceSets.main.java.srcDirs.first().parentFile.absolutePath) - workingDirectory = serverRunDir.absolutePath - } +// Ensure the shaded jar is produced during a normal build. +tasks.named('build') { + dependsOn 'shadowJar' } -// Creates a launch.json file for VSCode with the same configuration -tasks.register('generateVSCodeLaunch') { - def vscodeDir = file("$projectDir/.vscode") - def launchFile = file("$vscodeDir/launch.json") - doLast { - if (!vscodeDir.exists()) { - vscodeDir.mkdirs() +if (hasHytaleHome) { + // Create the working directory to run the server if it does not already exist. + def serverRunDir = file("$projectDir/run") + if (!serverRunDir.exists()) { + serverRunDir.mkdirs() + } + + def createServerRunArguments = { String srcDir -> + def programParameters = '--allow-op --disable-sentry --assets="' + "${hytaleHome}/install/$patchline/package/game/latest/Assets.zip" + '"' + def modPaths = [] + if (includes_pack.toBoolean()) { + modPaths << srcDir } - def programParams = createServerRunArguments("\${workspaceFolder}") - def launchConfig = [ - version: "0.2.0", - configurations: [ - [ - type: "java", - name: "HytaleServer", - request: "launch", - mainClass: "com.hypixel.hytale.Main", - args: programParams, - cwd: "\${workspaceFolder}/run" - ] + if (load_user_mods.toBoolean()) { + modPaths << "${hytaleHome}/UserData/Mods" + } + if (!modPaths.isEmpty()) { + programParameters += ' --mods="' + modPaths.join(',') + '"' + } + return programParameters + } + + // Creates a run configuration in IDEA that will run the Hytale server with + // your plugin and the default assets. + idea.project.settings.runConfigurations { + 'HytaleServer'(org.jetbrains.gradle.ext.Application) { + mainClass = 'com.hypixel.hytale.Main' + moduleName = project.idea.module.name + '.main' + programParameters = createServerRunArguments(sourceSets.main.java.srcDirs.first().parentFile.absolutePath) + workingDirectory = serverRunDir.absolutePath + } + } + + // Creates a launch.json file for VSCode with the same configuration + tasks.register('generateVSCodeLaunch') { + def vscodeDir = file("$projectDir/.vscode") + def launchFile = file("$vscodeDir/launch.json") + doLast { + if (!vscodeDir.exists()) { + vscodeDir.mkdirs() + } + def programParams = createServerRunArguments("\${workspaceFolder}") + def launchConfig = [ + version: "0.2.0", + configurations: [ + [ + type: "java", + name: "HytaleServer", + request: "launch", + mainClass: "com.hypixel.hytale.Main", + args: programParams, + cwd: "\${workspaceFolder}/run" + ] + ] ] - ] - launchFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(launchConfig)) + launchFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(launchConfig)) + } + } +} else { + tasks.register('generateVSCodeLaunch') { + doLast { + logger.lifecycle("Skipped VSCode launch configuration because hytale_home is not set or the install path is missing.") + } } } diff --git a/gradle.properties b/gradle.properties index e0e99eb..ba33300 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,11 @@ includes_pack=true # official launcher. patchline=release +# The exact Hytale build to compile against. Use the build string from the +# launcher (format YYYY.MM.DD-) so Gradle pulls the matching server jar +# for your selected patchline. +hytale_build=2026.01.27-734d39026 + # Determines if the development server should also load mods from the user's # standard mods folder. This lets you test mods by installing them where a # normal player would, instead of adding them as dependencies or adding them @@ -29,4 +34,4 @@ load_user_mods=false # manually. You may also want to use a custom path if you are building in # a non-standard environment like a build server. The home path should # the folder that contains the install and UserData folder. -# hytale_home=./test-file \ No newline at end of file +# hytale_home=./test-file -- 2.49.1 From b0d6afbd4c49c36e5aa772ea5e03c813deb1feff Mon Sep 17 00:00:00 2001 From: InvBoy <49959270+FedericoLeiva12@users.noreply.github.com> Date: Tue, 27 Jan 2026 23:00:05 -0300 Subject: [PATCH 2/7] Remove unused database driver dependencies Removed unused database driver dependencies. --- build.gradle | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 2b13069..1356cdf 100644 --- a/build.gradle +++ b/build.gradle @@ -52,10 +52,8 @@ dependencies { if (hasHytaleHome) { runtimeOnly(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar")) } - implementation('org.xerial:sqlite-jdbc:3.51.1.0') - implementation('com.j256.ormlite:ormlite-jdbc:6.1') - implementation('org.postgresql:postgresql:42.7.3') - implementation('com.mysql:mysql-connector-j:9.1.0') + + // Your dependencies here } repositories { -- 2.49.1 From bbd0265f2efbf87a05cba1106f4156ed71245507 Mon Sep 17 00:00:00 2001 From: DocW Date: Sun, 1 Feb 2026 14:13:52 -0500 Subject: [PATCH 3/7] Allow files in .vscode/ to be included in Git repo Allow the exclusion of files in the `.vscode/` directory to be overridden via negated patterns (gitignore patterns beginning with `!`) by changing the pattern in `.gitignore` from `.vscode/` to `.vscode/*` (i.e., by ignoring the files in `.vscode/` rather than the `.vscode/` directory itself). --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b7256e4..f81ceb8 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,7 @@ bin/ /.nb-gradle/ # VS Code -.vscode/ +.vscode/* # Mac OS .DS_Store -- 2.49.1 From 772dabc708cc53509a7e4947b9695be8b562ff5b Mon Sep 17 00:00:00 2001 From: DocW Date: Sun, 1 Feb 2026 14:19:36 -0500 Subject: [PATCH 4/7] Track VS Code settings in repository Add negated pattern to `.gitignore` for the VS Code settings file (`.vscode/settings.json`). --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f81ceb8..1db1534 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ bin/ # VS Code .vscode/* +!.vscode/settings.json # Mac OS .DS_Store -- 2.49.1 From 647fe815374788cd485a755c29f2db26b674d2ee Mon Sep 17 00:00:00 2001 From: DocW Date: Sun, 1 Feb 2026 14:20:58 -0500 Subject: [PATCH 5/7] Track VS Code Java formatter config in repo Add negated pattern to `.gitignore` for the VS Code Java formatter configuration file (`.vscode/java-formatter.xml`). --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1db1534..31342f7 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ bin/ # VS Code .vscode/* +!.vscode/java-formatter.xml !.vscode/settings.json # Mac OS -- 2.49.1 From be9968c345281cf59fc92fea3ce3802aff9797a6 Mon Sep 17 00:00:00 2001 From: Britakee <127439938+realBritakee@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:21:10 +0100 Subject: [PATCH 6/7] Switch to Groovy DSL; add runServer task Migrate the project from Gradle Kotlin DSL to Groovy DSL: update README to reference build.gradle/settings.gradle and change code blocks to Groovy. Remove build.gradle.kts. Add runServerJar and runServer tasks in build.gradle that depend on shadowJar and launch the Hytale server (uses hytaleHome paths, assets, and optional user mods). Bump plugin manifest version to 0.0.3 and set a concrete ServerVersion string. Fixed some issues. --- README.md | 20 ++++---- build.gradle | 27 ++++++++++ build.gradle.kts | 87 -------------------------------- src/main/resources/manifest.json | 4 +- 4 files changed, 39 insertions(+), 99 deletions(-) delete mode 100644 build.gradle.kts diff --git a/README.md b/README.md index 5ec290c..0eae348 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A minimal, ready-to-use template for creating Hytale plugins with modern build t ## Features -✅ **Modern Build System** - Gradle with Kotlin DSL +✅ **Modern Build System** - Gradle with Groovy DSL ✅ **Automated Testing** - Custom Gradle plugin for one-command server testing ✅ **Java 25** - Latest Java features ✅ **ShadowJar** - Automatic dependency bundling @@ -51,9 +51,9 @@ Your plugin JAR will be in: `build/libs/TemplatePlugin-1.0.0.jar` When ready to customize, edit these files: -**`settings.gradle.kts`:** +**`settings.gradle`:** -```kotlin +```groovy rootProject.name = "your-plugin-name" ``` @@ -139,9 +139,9 @@ TemplatePlugin/ │ └── resources/ │ └── manifest.json # Plugin metadata ├── .gitignore # Git ignore rules -├── build.gradle.kts # Build configuration +├── build.gradle # Build configuration ├── gradle.properties # Project properties -├── settings.gradle.kts # Project settings +├── settings.gradle # Project settings ├── LICENSE # MIT License └── README.md # This file ``` @@ -200,9 +200,9 @@ rm -rf run/ ### Adding Dependencies -Edit `build.gradle.kts`: +Edit `build.gradle`: -```kotlin +```groovy dependencies { // Hytale API (provided by server) compileOnly(files("./HytaleServer.jar")) @@ -221,9 +221,9 @@ dependencies { **Usage:** -Edit `build.gradle.kts`: +Edit `build.gradle`: -```kotlin +```groovy runHytale { jarUrl = "url to hytale server jar" } @@ -322,7 +322,7 @@ GitHub Actions will automatically build and create a release with your plugin JA ### Server Won't Start -1. Check that `jarUrl` in `build.gradle.kts` is correct +1. Check that `jarUrl` in `build.gradle` is correct 2. Verify Java 25 is installed: `java -version` 3. Check logs in `run/logs/` diff --git a/build.gradle b/build.gradle index 1356cdf..ad87ae3 100644 --- a/build.gradle +++ b/build.gradle @@ -121,6 +121,33 @@ if (hasHytaleHome) { return programParameters } + def serverJar = file("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar") + def assetsZip = file("$hytaleHome/install/$patchline/package/game/latest/Assets.zip") + def shadowJarTask = tasks.named('shadowJar') + + tasks.register('runServerJar', JavaExec) { + dependsOn shadowJarTask + mainClass = 'com.hypixel.hytale.Main' + classpath = files(serverJar) + workingDir = serverRunDir.absolutePath + doFirst { + def modPaths = [shadowJarTask.get().archiveFile.get().asFile.absolutePath] + if (load_user_mods.toBoolean()) { + modPaths << "${hytaleHome}/UserData/Mods" + } + setArgs([ + '--allow-op', + '--disable-sentry', + "--assets=${assetsZip}", + "--mods=${modPaths.join(',')}" + ]) + } + } + + tasks.register('runServer') { + dependsOn 'runServerJar' + } + // Creates a run configuration in IDEA that will run the Hytale server with // your plugin and the default assets. idea.project.settings.runConfigurations { diff --git a/build.gradle.kts b/build.gradle.kts deleted file mode 100644 index 372dbb0..0000000 --- a/build.gradle.kts +++ /dev/null @@ -1,87 +0,0 @@ -plugins { - id("java-library") - id("com.gradleup.shadow") version "9.3.1" - id("run-hytale") -} - -group = findProperty("pluginGroup") as String? ?: "com.example" -version = findProperty("pluginVersion") as String? ?: "1.0.0" -description = findProperty("pluginDescription") as String? ?: "A Hytale plugin template" - -repositories { - mavenLocal() - mavenCentral() -} - -dependencies { - // Hytale Server API (provided by server at runtime) - compileOnly(files("./libs/HytaleServer.jar")) - - // Common dependencies (will be bundled in JAR) - implementation("com.google.code.gson:gson:2.10.1") - implementation("org.jetbrains:annotations:24.1.0") - - // Test dependencies - testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") -} - -// Configure server testing -runHytale { - jarUrl = "./libs/HytaleServer.jar" - assetsPath = "./libs/Assets.zip" -} - -tasks { - // Configure Java compilation - compileJava { - options.encoding = Charsets.UTF_8.name() - options.release = 25 - } - - // Configure resource processing - processResources { - filteringCharset = Charsets.UTF_8.name() - - // Replace placeholders in manifest.json - val props = mapOf( - "group" to project.group, - "version" to project.version, - "description" to project.description - ) - inputs.properties(props) - - filesMatching("manifest.json") { - expand(props) - } - } - - // Configure ShadowJar (bundle dependencies) - shadowJar { - archiveBaseName.set(rootProject.name) - archiveClassifier.set("") - - // Relocate dependencies to avoid conflicts - relocate("com.google.gson", "com.yourplugin.libs.gson") - - // Minimize JAR size (removes unused classes) - minimize() - } - - // Configure tests - test { - useJUnitPlatform() - } - - // Make build depend on shadowJar - build { - dependsOn(shadowJar) - } -} - -// Configure Java toolchain -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(25)) - } -} diff --git a/src/main/resources/manifest.json b/src/main/resources/manifest.json index 169a0cc..5c8357c 100644 --- a/src/main/resources/manifest.json +++ b/src/main/resources/manifest.json @@ -1,7 +1,7 @@ { "Group": "Example", "Name": "ExamplePlugin", - "Version": "0.0.2", + "Version": "0.0.3", "Description": "An example plugin for HyTale!", "Authors": [ { @@ -9,7 +9,7 @@ } ], "Website": "example.org", - "ServerVersion": "*", + "ServerVersion": "2026.02.17-255364b8e", "Dependencies": { }, -- 2.49.1 From b6a2a9d51509a9b3a3d8e39657127f2626c600ee Mon Sep 17 00:00:00 2001 From: Britakee <127439938+realBritakee@users.noreply.github.com> Date: Wed, 18 Feb 2026 08:57:15 +0100 Subject: [PATCH 7/7] =?UTF-8?q?updated=20the=20template=20so=20it=20finds?= =?UTF-8?q?=20Hytale=20even=20when=20it=20isn=E2=80=99t=20in=20the=20defau?= =?UTF-8?q?lt=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 9 +++++---- src/main/resources/manifest.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index ad87ae3..e1ecb6b 100644 --- a/build.gradle +++ b/build.gradle @@ -9,8 +9,9 @@ import org.gradle.internal.os.OperatingSystem ext { if (project.hasProperty('hytale_home')) { hytaleHome = project.findProperty('hytale_home') - } - else { + } else if (System.getenv('HYTALE_HOME')) { + hytaleHome = System.getenv('HYTALE_HOME') + } else { def os = OperatingSystem.current() if (os.isWindows()) { hytaleHome = "${System.getProperty("user.home")}/AppData/Roaming/Hytale" @@ -27,8 +28,8 @@ ext { } } -def hytaleHomePath = project.findProperty('hytaleHome') -def hasHytaleHome = hytaleHomePath && file(hytaleHomePath).exists() +def hytaleHomePath = ext.has('hytaleHome') ? hytaleHome : null +def hasHytaleHome = (hytaleHomePath != null) && file(hytaleHomePath).exists() if (!hasHytaleHome) { logger.lifecycle("Hytale install not detected; run configs that launch the server will be skipped. Set -Phytale_home=/path/to/Hytale to enable them.") } diff --git a/src/main/resources/manifest.json b/src/main/resources/manifest.json index 5c8357c..c39edab 100644 --- a/src/main/resources/manifest.json +++ b/src/main/resources/manifest.json @@ -1,7 +1,7 @@ { "Group": "Example", "Name": "ExamplePlugin", - "Version": "0.0.3", + "Version": "0.0.2", "Description": "An example plugin for HyTale!", "Authors": [ { -- 2.49.1