···8899jobs:
1010 build:
1111- runs-on: kotlin # sickday/kotlin:latest (JDK 21; Gradle via ./gradlew wrapper)
1111+ runs-on: kotlin # sickday/kotlin:latest (JDK 21 + kotlinc + jar)
1212 steps:
1313 - uses: actions/checkout@v4
14141515- - name: Cache Gradle
1616- uses: actions/cache@v4
1717- with:
1818- path: |
1919- ~/.gradle/caches
2020- ~/.gradle/wrapper
2121- key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
2222- restore-keys: gradle-${{ runner.os }}-
1515+ # build-client.sh runs `kotlinc src/main/kotlin -include-runtime
1616+ # -jvm-target 21` then sets the Main-Class via `jar`. Both tools are in the
1717+ # image. It exports JAVA_OPTS=-Xmx3g by default (fine on the runner). No
1818+ # Gradle: the client has no third-party deps (config is java.util.Properties).
1919+ - name: Build the client jar
2020+ run: bash build-client.sh
23212424- # The wrapper self-downloads Gradle 9.0; the image only provides JDK 21.
2525- - name: Build jar
2626- run: ./gradlew --no-daemon clean jar
2222+ # Testers get the jar + a launcher for their OS + a default config, zipped
2323+ # into one folder — they double-click run.command (macOS) / run.bat
2424+ # (Windows) or ./run.sh (Linux); nobody has to know how to launch a jar.
2525+ # config/server.properties is gitignored (local), so ship the committed
2626+ # EXAMPLE as the default — testers edit net.address to point at the server.
2727+ - name: Bundle jar + launch scripts + config
2828+ run: |
2929+ mkdir -p dist/hla-client/config
3030+ cp hla-client.jar run.sh run.command run.bat dist/hla-client/
3131+ cp config/EXAMPLE-server.properties dist/hla-client/config/server.properties
3232+ chmod +x dist/hla-client/run.sh dist/hla-client/run.command
3333+ (cd dist && zip -r hla-client.zip hla-client)
27342828- - name: Publish jar to the package registry
3535+ - name: Publish bundle to the package registry
2936 if: github.ref == 'refs/heads/main'
3037 run: |
3131- JAR=$(ls build/libs/*.jar | head -1)
3238 curl -fsSL --user "${{ github.actor }}:${{ secrets.REGISTRY_TOKEN }}" \
3333- --upload-file "$JAR" \
3434- "https://git.dunk.works/api/packages/${{ github.repository_owner }}/generic/hla-client/${{ github.sha }}/$(basename "$JAR")"
3939+ --upload-file dist/hla-client.zip \
4040+ "https://git.dunk.works/api/packages/${{ github.repository_owner }}/generic/hla-client/${{ github.sha }}/hla-client.zip"
3541 # REGISTRY_TOKEN = a Forgejo PAT with write:package (org/repo Actions secret).
+49
build-client.sh
···11+#!/usr/bin/env bash
22+#
33+# Build the High Level Alchemy RS377 client into a single self-contained jar.
44+#
55+# Compiles every .kt under src/main/kotlin with kotlinc, bundling the Kotlin
66+# runtime so the jar runs with a bare `java -jar`. The Main-Class is set to
77+# com.jagex.runescape.Game (its companion `@JvmStatic fun main` is exposed as a
88+# static method on that class).
99+#
1010+# The client has no third-party runtime dependencies — configuration is parsed
1111+# with the JDK's java.util.Properties — so a clean kotlinc build needs nothing on
1212+# the classpath. The jars under lib/ are test-only and not used here.
1313+#
1414+# A full kotlinc build from src/ every time keeps "what you run" identical to
1515+# "what's in src/", sidestepping stale IDE/Gradle incremental-build surprises.
1616+#
1717+# Usage: ./build-client.sh
1818+set -euo pipefail
1919+2020+CLIENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
2121+SRC_DIR="$CLIENT_DIR/src/main/kotlin"
2222+OUT_JAR="$CLIENT_DIR/hla-client.jar"
2323+MAIN_CLASS="com.jagex.runescape.Game"
2424+2525+KOTLINC="${KOTLINC:-kotlinc}"
2626+JAR="${JAR_BIN:-jar}"
2727+2828+# kotlinc can be memory-hungry compiling the full client; give it room.
2929+export JAVA_OPTS="${JAVA_OPTS:-"-Xmx3g"}"
3030+3131+command -v "$KOTLINC" >/dev/null 2>&1 || { echo "error: kotlinc not found (set \$KOTLINC)"; exit 1; }
3232+command -v "$JAR" >/dev/null 2>&1 || { echo "error: jar not found (set \$JAR_BIN)"; exit 1; }
3333+[ -d "$SRC_DIR" ] || { echo "error: src dir not found at $SRC_DIR"; exit 1; }
3434+3535+echo "[build] compiling $(find "$SRC_DIR" -name '*.kt' | wc -l | tr -d ' ') Kotlin files from $SRC_DIR ..."
3636+echo "[build] this is a full (non-incremental) compile; expect ~1-2 min."
3737+3838+# -include-runtime bundles kotlin-stdlib so the jar is standalone.
3939+# -jvm-target matches the JDK the run scripts use.
4040+"$KOTLINC" "$SRC_DIR" \
4141+ -include-runtime \
4242+ -jvm-target 21 \
4343+ -d "$OUT_JAR"
4444+4545+# kotlinc doesn't write a Main-Class; set it so `java -jar` works.
4646+"$JAR" --update --file "$OUT_JAR" --main-class "$MAIN_CLASS"
4747+4848+echo "[build] done -> $OUT_JAR"
4949+echo "[build] run it with: ./run.sh"
gradlew
+19
run.bat
···11+@echo off
22+REM High Level Alchemy client launcher — Windows. Double-click to run.
33+setlocal
44+cd /d "%~dp0"
55+66+where java >nul 2>nul
77+if errorlevel 1 (
88+ echo Java isn't installed. Install Java 21+ from https://adoptium.net and try again.
99+ pause
1010+ exit /b 1
1111+)
1212+if not exist "hla-client.jar" (
1313+ echo hla-client.jar not found next to this script.
1414+ pause
1515+ exit /b 1
1616+)
1717+1818+java -jar hla-client.jar %*
1919+pause
+26
run.command
···11+#!/bin/bash
22+#
33+# High Level Alchemy client launcher for macOS — double-click in Finder.
44+#
55+# First time, macOS may block it ("unidentified developer"): right-click the
66+# file -> Open -> Open, just once. (Or in Terminal: xattr -d com.apple.quarantine run.command)
77+#
88+# Finder launches double-clicked scripts from your home folder, so we cd to the
99+# script's own folder first to find the jar and ./config/server.properties next to it.
1010+cd "$(dirname "$0")" || exit 1
1111+1212+JAR="hla-client.jar"
1313+1414+if ! command -v java >/dev/null 2>&1; then
1515+ echo "Java isn't installed. Install Java 21+ (https://adoptium.net) and try again."
1616+ read -r -p "Press Return to close..."
1717+ exit 1
1818+fi
1919+if [ ! -f "$JAR" ]; then
2020+ echo "hla-client.jar not found next to this script."
2121+ read -r -p "Press Return to close..."
2222+ exit 1
2323+fi
2424+2525+java -jar "$JAR" "$@"
2626+read -r -p "Client closed. Press Return to close this window..."
+24
run.sh
···11+#!/usr/bin/env bash
22+#
33+# High Level Alchemy client launcher — Linux / macOS (terminal).
44+# macOS users double-clicking in Finder: use run.command instead.
55+#
66+# Just run it: ./run.sh
77+# Custom args: ./run.sh <args...> (Game.main ignores args; everything comes
88+# from ./config/server.properties)
99+set -euo pipefail
1010+1111+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1212+cd "$DIR" || exit 1 # so the client finds ./config/server.properties beside the jar
1313+JAR="$DIR/hla-client.jar"
1414+1515+if ! command -v java >/dev/null 2>&1; then
1616+ echo "Java isn't installed. Install Java 21+ (https://adoptium.net) and try again."
1717+ exit 1
1818+fi
1919+if [ ! -f "$JAR" ]; then
2020+ echo "hla-client.jar not found next to this script."
2121+ exit 1
2222+fi
2323+2424+exec java -jar "$JAR" "$@"