Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ jobs:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up JDK 21
- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
java-version: "25"

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down Expand Up @@ -80,11 +80,11 @@ jobs:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up JDK 21
- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
java-version: "25"

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ jobs:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up JDK 21
- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
java-version: "25"

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ The preview project uses normal ModularUI2 classes and widget APIs. There is no
## Requirements

- Windows, Linux, or macOS;
- JDK 21;
- JDK 25;
- internet access on the first run so the Gradle Wrapper can download build dependencies.

Gradle does not need to be installed separately.

## Install a release

Download the ZIP on Windows or the `tar.gz` archive on Linux and macOS, extract it, and run `preview.bat help` or `./preview.sh help`. Release archives already contain the compiled previewer and do not require Gradle. They still require JDK 21 because preview projects compile Java source code on every build.
Download the ZIP on Windows or the `tar.gz` archive on Linux and macOS, extract it, and run `preview.bat help` or `./preview.sh help`. Release archives already contain the compiled previewer and do not require Gradle. They still require JDK 25 because preview projects compile Java source code on every build.

The launchers use `JAVA_HOME` when it is set, otherwise they use `java` and `javac` from `PATH`. A JRE without `javac` is not sufficient.

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repositories {

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
languageVersion.set(JavaLanguageVersion.of(25))
}
}

Expand Down
4 changes: 4 additions & 0 deletions integrations/galaxia-starmap/actions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
capture orbital-overview
move 28 235
click left
capture mars-expanded
5 changes: 5 additions & 0 deletions integrations/galaxia-starmap/preview.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
preview.entrypoint=example.GalaxiaStarmapPreview
screen.width=1920
screen.height=1080
gui.scale=2
screen.background=#000000
3 changes: 3 additions & 0 deletions integrations/galaxia-starmap/runtime-classpath.example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Generate runtime-classpath.txt from Galaxia's runtime classpath.
# Include Galaxia's compiled classes and resources, but omit ModularUI and ModularUI2;
# the previewer supplies the versions it was built and verified against.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package example;

import com.cleanroommc.modularui.value.sync.PanelSyncManager;
import com.gtnewhorizons.galaxia.client.gui.orbitalGUI.GalacticChartGui;
import com.gtnewhorizons.galaxia.registry.celestial.CelestialRegistry;
import com.gtnewhorizons.galaxia.registry.celestial.asteroid.AsteroidFieldOrbitResolver;
import com.gtnewhorizons.galaxia.registry.orbital.OrbitalMechanics;

import dev.modularui.preview.PreviewEntrypoint;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;

import gregtech.api.enums.Materials;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;

/** Runs Galaxia's production Starmap builder against representative local client state. */
public final class GalaxiaStarmapPreview implements PreviewEntrypoint {

@Override
public String owner() {
return "galaxia";
}

@Override
public Class<?> previewedClass() {
return GalacticChartGui.class;
}

@Override
public Object createPanel(Context context) {
initializeFmlSide();
setVanillaBootstrap(true);
try {
if (Block.blockRegistry.getObject("water") == null) {
Block.registerBlocks();
}
Class.forName("net.minecraft.init.Blocks", true, getClass().getClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Failed to initialize vanilla block constants", e);
} finally {
setVanillaBootstrap(false);
}
if (Materials.Air.getGas(1L) == null) {
Fluid air = new Fluid("air");
FluidRegistry.registerFluid(air);
Materials.Air.mGas = air;
}
OrbitalMechanics.registerMinorBodyResolver(AsteroidFieldOrbitResolver.INSTANCE);
CelestialRegistry.freezeAndBake();

EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer;
player.dimension = 0;

return new GalacticChartGui().build((PanelSyncManager) context.panelSyncManager(), player);
}

private static void setVanillaBootstrap(boolean active) {
try {
Class<?> loader = Class.forName("cpw.mods.fml.common.Loader");
loader.getMethod(active ? "beginVanillaBootstrap" : "endVanillaBootstrap").invoke(null);
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Preview Loader does not support vanilla registry bootstrapping", e);
}
}

private static void initializeFmlSide() {
try {
Class<?> log = Class.forName("cpw.mods.fml.relauncher.FMLRelaunchLog");
java.lang.reflect.Field field = log.getDeclaredField("side");
field.setAccessible(true);
if (field.get(null) == null) {
field.set(null, cpw.mods.fml.relauncher.Side.CLIENT);
}
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Failed to initialize the local FML side", e);
}
}

}
6 changes: 3 additions & 3 deletions preview.bat
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ if defined JAVA_HOME (
set "PREVIEW_JAVAC=%JAVA_HOME%\bin\javac.exe"
) else (
where java.exe >nul 2>nul || (
echo ModularUI2 Preview requires JDK 21. Set JAVA_HOME or add java and javac to PATH. 1>&2
echo ModularUI2 Preview requires JDK 25. Set JAVA_HOME or add java and javac to PATH. 1>&2
exit /b 2
)
where javac.exe >nul 2>nul || (
Expand Down Expand Up @@ -51,8 +51,8 @@ for /f "tokens=1,2,3" %%A in ('"%PREVIEW_JAVA%" -version 2^>^&1') do if not defi
for /f "tokens=1 delims=." %%V in ("%PREVIEW_JAVA_VERSION%") do set "PREVIEW_JAVA_MAJOR=%%V"
set "PREVIEW_JAVA_MAJOR_NUMBER=0"
set /a PREVIEW_JAVA_MAJOR_NUMBER=%PREVIEW_JAVA_MAJOR% >nul 2>nul
if %PREVIEW_JAVA_MAJOR_NUMBER% LSS 21 (
echo ModularUI2 Preview requires JDK 21 or newer; found %PREVIEW_JAVA_VERSION%. 1>&2
if %PREVIEW_JAVA_MAJOR_NUMBER% LSS 25 (
echo ModularUI2 Preview requires JDK 25 or newer; found %PREVIEW_JAVA_VERSION%. 1>&2
exit /b 2
)
exit /b 0
6 changes: 3 additions & 3 deletions preview.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ else
fi

if [ -z "$preview_java" ] || [ ! -x "$preview_java" ]; then
echo "ModularUI2 Preview requires JDK 21. Set JAVA_HOME or add java and javac to PATH." >&2
echo "ModularUI2 Preview requires JDK 25. Set JAVA_HOME or add java and javac to PATH." >&2
exit 2
fi
if [ -z "$preview_javac" ] || [ ! -x "$preview_javac" ]; then
Expand All @@ -35,8 +35,8 @@ case "$java_major" in
exit 2
;;
esac
if [ "$java_major" -lt 21 ]; then
echo "ModularUI2 Preview requires JDK 21 or newer; found $java_version." >&2
if [ "$java_major" -lt 25 ]; then
echo "ModularUI2 Preview requires JDK 25 or newer; found $java_version." >&2
exit 2
fi

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.cleanroommc.modularui.utils;

import dev.modularui.preview.PreviewDrawContext;

public final class GlStateManager {

private GlStateManager() {}

public static void color(float red, float green, float blue, float alpha) {}
public static void color(float red, float green, float blue, float alpha) {
PreviewDrawContext.color(red, green, blue, alpha);
}
}
9 changes: 9 additions & 0 deletions src/main/java/cpw/mods/fml/common/ICrashCallable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package cpw.mods.fml.common;

/** Minimal Forge crash-report callback contract used by the preview runtime. */
public interface ICrashCallable {

String call() throws Exception;

String getLabel();
}
39 changes: 35 additions & 4 deletions src/main/java/cpw/mods/fml/common/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,55 @@
/** Minimal mod lookup used by ModularUI2 while running outside Forge. */
public final class Loader {

private static final Loader INSTANCE = new Loader();
private static Loader instance = new Loader();
private static final ModContainer ACTIVE_MOD_CONTAINER = () -> "preview";
private static final ModContainer MINECRAFT_CONTAINER = () -> "minecraft";
private static boolean bootstrappingVanilla;
@SuppressWarnings("unused")
private java.util.List<ModContainer> mods = java.util.List.of();
@SuppressWarnings("unused")
private Map<String, ModContainer> namedMods = Map.of();
@SuppressWarnings("unused")
private Object modController;

private Loader() {}

public static Loader instance() {
return INSTANCE;
return instance;
}

public static boolean isModLoaded(String modId) {
return false;
}

public Map<String, ModContainer> getIndexedModList() {
return Map.of();
return namedMods;
}

public ModContainer activeModContainer() {
return ACTIVE_MOD_CONTAINER;
return bootstrappingVanilla ? MINECRAFT_CONTAINER : ACTIVE_MOD_CONTAINER;
}

public ICrashCallable getCallableCrashInformation() {
return new ICrashCallable() {

@Override
public String call() {
return "";
}

@Override
public String getLabel() {
return "FML";
}
};
}

public static void beginVanillaBootstrap() {
bootstrappingVanilla = true;
}

public static void endVanillaBootstrap() {
bootstrappingVanilla = false;
}
}
Loading
Loading