Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); New blog post: Planet Search Overhaul (07/13/24)

Author Topic: Mod Developers: Docker image for building mods  (Read 1877 times)

xuinghj

  • Ensign
  • *
  • Posts: 2
    • View Profile
Mod Developers: Docker image for building mods
« on: June 01, 2024, 06:17:19 PM »

Hi all, I wanted to share a docker image that can be used to easily build mods, without worrying about environment setup.

This is useful if you want to have a pre-configured environment with all the build tools and SDK configured. Where you can just drop in some Java source files and point it at your Starsector directory, then build jars against your current game version. Supports any Java/Gradle version by just updating the numbers.

This is especially great if you don't want to configure IntelliJ manually on every machine, and you want to be able to simply drop in the files and run a build without manually installing dependencies.

I recommend some familiarity with Docker.

This sets up a JDK 8 Debian container with Gradle 7.2, which support outputting Java 7 bytecode to create mod jars that are fully compatible with current Starsector.

Code
FROM debian:bookworm-slim

# install dependencies
RUN apt update \
    # core
    && apt -y install bash curl wget unzip git apt-transport-https gnupg \
    # jdk 8
    && wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | apt-key add - \
    && echo "deb https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list \
    && apt update && apt -y install temurin-8-jdk \
    # cleanup
    && rm -rf /var/lib/apt/lists/* && apt -y autoremove && apt -y clean

# install gradle 7.2
RUN wget -O /tmp/gradle-7.2-all.zip https://services.gradle.org/distributions/gradle-7.2-all.zip \
    && mkdir -p /opt/gradle \
    && unzip -q -d /opt/gradle /tmp/gradle-7.2-all.zip \
    && rm /tmp/gradle-7.2-all.zip

# run shell
CMD ["/bin/bash", "-l"]

This is meant to be used for a mod that can be built with Gradle. I was using this gradle build script: https://github.com/wispborne/starsector-mod-template/blob/master/build.gradle.kts.

I modified it slightly to allow specifying the starsector dir as a Gradle property:
Code
/**
 * Where your Starsector game is installed to. Can be set using the `starsector.dir` Gradle property.
 */
val starsectorDirectory =
    if (providers.gradleProperty("starsector.dir").isPresent) providers.gradleProperty("starsector.dir").get()
    else "C:/Program Files (x86)/Fractal Softworks/Starsector"
println("Starsector directory: $starsectorDirectory")

If you use this image and any gradle project, you can build and run the container like this:

Code
docker build -f ./starsector_mod_builder.docker -t localhost/starsector_mod_builder
docker run --rm -it -v $(pwd):/prj -v /path/to/your/starsector/dir:/starsector localhost/starsector_mod_builder /prj/your_build_script.sh

The above will mount your starsector gamedir into the container, and then run the build script inside the container

For a build script, use something as simple as:
Code
cd /prj
/opt/gradle/gradle-7.2/bin/gradle -Pstarsector.dir="/starsector" build

This will then build jars for you!

I hope this is helpful.
Logged

Wispborne

  • Captain
  • ****
  • Posts: 482
  • Discord: wispborne
    • View Profile
Re: Mod Developers: Docker image for building mods
« Reply #1 on: June 03, 2024, 07:00:55 AM »

It's neat but, unless I'm mistaken, it'll require a few GB of stuff to be automatically downloaded, plus make compiling take longer (Gradle's quite a bit slower than just using IntelliJ's build stuff).

The niche use case where it's useful, as you point out, is when you want to build on a computer that you have Starsector on but don't want to install IntelliJ on, or want to do a headless build.

Maybe if you want to make a self-hosted GitHub Actions runner? Or are running another CI/CD pipeline locally. It could be suggested as a simpler way for users that want to tweak a single hardcoded value in a mod and recompile than setting up IntelliJ, but without true step-by-step instructions for something as complex as Docker, IntelliJ ends up being easier.

Neat. But quite niche. The self-hosted Actions runner is a cool thought, especially if it were something opened up for any modder to use, but that'd require figuring out arbitrary mod dependencies, which is...effectively impossible to do automatically at present.
Logged
Mod Managers: TriOS & SMOL | Mod: Persean Chronicles | Tool: VRAM Estimator | Tool: Forum+Discord Mod Database | If I'm inactive for 3 months, anyone can use any of my work for anything (except selling it or its derivatives).

xuinghj

  • Ensign
  • *
  • Posts: 2
    • View Profile
Re: Mod Developers: Docker image for building mods
« Reply #2 on: June 04, 2024, 01:47:05 AM »

It's neat but, unless I'm mistaken, it'll require a few GB of stuff to be automatically downloaded, plus make compiling take longer (Gradle's quite a bit slower than just using IntelliJ's build stuff).

The niche use case where it's useful, as you point out, is when you want to build on a computer that you have Starsector on but don't want to install IntelliJ on, or want to do a headless build.

Maybe if you want to make a self-hosted GitHub Actions runner? Or are running another CI/CD pipeline locally. It could be suggested as a simpler way for users that want to tweak a single hardcoded value in a mod and recompile than setting up IntelliJ, but without true step-by-step instructions for something as complex as Docker, IntelliJ ends up being easier.

Neat. But quite niche. The self-hosted Actions runner is a cool thought, especially if it were something opened up for any modder to use, but that'd require figuring out arbitrary mod dependencies, which is...effectively impossible to do automatically at present.

I mean, in my testing,

Docker image is: 731 MB, which is quite reasonable for the dependencies being pulled in. That's almost all from Java dependencies.

In my testing, Gradle is quite fast, and you can also just mount cache dirs into your host system tmpfs as needed.

Personally, I don't have a need for an IDE so I like being able to do headless builds. But as you said, this is also very useful for running automated builds, or for updating/rebuilding an existing mod with minor tweaks or for a new starsector version. Mounting your starsector dir into a container makes this fully automated and dead easy.

Also, his will find jars to link against in the starsector mod dir: assuming you only have a single copy of LazyLib/MagicLib, then it should automatically find and link against those jars in your game dir.

Definitely this should work well with Actions. You'll just have to unzip the library jars like lazylib into the starsector gamedir, then you can run an automated build with this image and gradle, etc...
« Last Edit: June 04, 2024, 01:51:25 AM by xuinghj »
Logged

Princess of Evil

  • Admiral
  • *****
  • Posts: 746
  • Balance is not an endpoint, but a direction.
    • View Profile
Re: Mod Developers: Docker image for building mods
« Reply #3 on: June 04, 2024, 02:13:34 AM »

Gradle, if used extremely carefully, is "fast enough", but nowhere near "IDE" fast - absolute most of mod compilation weight in this case would be gradle being the slowest program on the planet, especially if you consider that even javac used directly via command line caches things (or rather, doesn't recompile classes that didn't change).

Frankly, i don't see the use case either. If you have a game you mod and you have some kind of a problem with compiling it in your IDE, adding gradle just means you now have two problems.

Honestly, i just use javac directly. The only downside is that you need to list every file, which can be done automatically in bash or batch, but i just do it manually:

Spoiler
Code: batch
ECHO 18+ doesn't work.
"C:\Program Files\Java\jdk-17.0.9\bin\javac" -classpath "..\..\starsector-core\janino.jar;..\..\starsector-core\commons-compiler.jar;..\..\starsector-core\commons-compiler-jdk.jar;..\..\starsector-core\starfarer.api.jar;..\..\starsector-core\starfarer_obf.jar;..\..\starsector-core\jogg-0.0.7.jar;..\..\starsector-core\jorbis-0.0.15.jar;..\..\starsector-core\json.jar;..\..\starsector-core\lwjgl.jar;..\..\starsector-core\jinput.jar;..\..\starsector-core\log4j-1.2.9.jar;..\..\starsector-core\lwjgl_util.jar;..\..\starsector-core\fs.sound_obf.jar;..\..\starsector-core\fs.common_obf.jar;..\..\starsector-core\xstream-1.4.10.jar;..\LazyLib\jars\LazyLib.jar"  --release 7 "src\data\princess\CarrierUI.java"
jar cf jar\carrierui.jar -C src data\princess\CarrierUI.class
pause
[close]
Logged
Proof that you don't need to know any languages to translate, you just need to care.