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
6 changes: 5 additions & 1 deletion .github/workflows/build-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ jobs:

test-project:
strategy:
max-parallel: 6
matrix:
os: [ubuntu-latest, windows-latest]
project: [testproject, legacytest]
recomp: ["recomp", "no recomp"]
runs-on: ${{ matrix.os }}
name: Test ${{ matrix.project }} on ${{ matrix.os }}
name: Test ${{ matrix.project }} on ${{ matrix.os }} (${{ matrix.recomp }})
env:
CI: ${{ matrix.recomp == 'no recomp' }}
steps:
- name: Checkout project sources
uses: neoforged/actions/checkout@main
Expand Down
13 changes: 13 additions & 0 deletions LEGACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ legacyForge {
}
```

## Disabling Decompilation and Recompilation
As of MDG Legacy 2.0.124, the decompilation/recompilation pipeline can be disabled, similarly to the regular plugin.
To disable it in CI, use the following:
```groovy
legacyForge {
enable {
forgeVersion = "..." // or mcpVersion = "..." if running in Vanilla mode
// Disable recompilation if the "CI" environment variable is set to true. It is automatically set by GitHub Actions.
disableRecompilation = System.getenv("CI") == "true"
}
}
```

## Mixins

You need to create so-called "refmaps" for Mixin, which convert the names you used to declare injection points and reference other parts of Minecraft code to the names used at runtime (SRG).
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@ neoForge {
}
```

## Disabling Decompilation and Recompilation
By default, MDG will use the [NeoForm](https://github.com/neoforged/NeoForm) decompilation/recompilation pipeline to produce
Minecraft sources and a matching compiled game jar. This leads to a great debugging experience, at the cost of longer setup times.

As of MDG 2.0.124, an alternative pipeline can be used, which will skip decompilation and recompilation entirely!
We recommend leaving recompilation on by default, but disabling it when running on CI such as GitHub Actions.

To do so, replace:
```groovy
neoForge {
version = "..." // or neoFormVersion = "..."
}
```
By:
```groovy
neoForge {
enable {
version = "..." // or neoFormVersion = "..."
// Disable recompilation if the "CI" environment variable is set to true. It is automatically set by GitHub Actions.
disableRecompilation = System.getenv("CI") == "true"
}
}
```

## Common Issues

### Clicking "Attach Sources" does nothing when viewing a Minecraft class (IntelliJ IDEA)
Expand Down
5 changes: 4 additions & 1 deletion legacytest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ java {
}

legacyForge {
mcpVersion = '1.19.2'
enable {
mcpVersion = '1.19.2'
disableRecompilation = System.getenv("CI") == "true"
}
}

publishing {
Expand Down
6 changes: 4 additions & 2 deletions legacytest/forge/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ plugins {
}

repositories {
mavenLocal()
maven {
name = "Jared's maven"
url = "https://maven.blamejared.com/"
Expand Down Expand Up @@ -33,7 +32,10 @@ dependencies {
}

legacyForge {
version = '1.20.1-47.3.12'
enable {
forgeVersion = '1.20.1-47.3.12'
disableRecompilation = System.getenv("CI") == "true"
}
runs {
client {
client()
Expand Down
11 changes: 11 additions & 0 deletions legacytest/forge/src/main/java/mymod/MyMod.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package mymod;

import net.minecraft.DetectedVersion;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.EnderChestBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraftforge.fml.common.Mod;

@Mod("mymod")
Expand All @@ -9,6 +13,13 @@ public void run() {
DetectedVersion.tryDetectVersion();
}

public static void doStuff() {
// Test our AT
ServerLevel.END_SPAWN_POINT = new BlockPos(1, 2, 3);
// Test a Forge AT (in a class that is not binpatched)
var block = new EnderChestBlock(BlockBehaviour.Properties.of());
}

@javax.annotation.Nullable
private static Object javaxNullableTest() {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public-f net.minecraft.server.level.ServerLevel f_8562_ # END_SPAWN_POINT
5 changes: 4 additions & 1 deletion legacytest/forgedownstream/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ dependencies {
}

legacyForge {
version = '1.20.1-47.3.0'
enable {
forgeVersion = '1.20.1-47.3.0'
disableRecompilation = System.getenv("CI") == "true"
}
}

var copyJarJar = tasks.register('copyJarJar', Copy) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public abstract class LegacyForgeModdingSettings {

private Set<SourceSet> enabledSourceSets = new HashSet<>();

private boolean disableRecompilation = false;

private boolean obfuscateJar = true;

@Inject
Expand Down Expand Up @@ -78,6 +80,21 @@ public void setEnabledSourceSets(Set<SourceSet> enabledSourceSets) {
this.enabledSourceSets = enabledSourceSets;
}

/**
* {@code true} if MDG should skip the NeoForm decompilation/recompilation pipeline,
* and instead apply transforms on the .class files and use binary patches.
* This leads to a faster setup since Minecraft doesn't need to be decompiled,
* however source files will not be available.
* {@code false} by default.
*/
public boolean isDisableRecompilation() {
return disableRecompilation;
}

public void setDisableRecompilation(boolean disableRecompilation) {
this.disableRecompilation = disableRecompilation;
}

/**
* {@return true if default reobfuscation task should be created}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ public void enable(Project project, LegacyForgeModdingSettings settings, LegacyF
artifactNamingStrategy,
configurations.getByName(DataFileCollections.CONFIGURATION_ACCESS_TRANSFORMERS),
configurations.getByName(DataFileCollections.CONFIGURATION_INTERFACE_INJECTION_DATA),
versionCapabilities);
versionCapabilities,
settings.isDisableRecompilation());

var runs = ModDevRunWorkflow.create(
project,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public abstract class ModdingVersionSettings {

private Set<SourceSet> enabledSourceSets = new HashSet<>();

private boolean disableRecompilation = false;

@Inject
public ModdingVersionSettings(Project project) {
// By default, enable modding deps only for the main source set
Expand Down Expand Up @@ -60,4 +62,19 @@ public Set<SourceSet> getEnabledSourceSets() {
public void setEnabledSourceSets(Set<SourceSet> enabledSourceSets) {
this.enabledSourceSets = enabledSourceSets;
}

/**
* {@code true} if MDG should skip the NeoForm decompilation/recompilation pipeline,
* and instead apply transforms on the .class files and use binary patches.
* This leads to a faster setup since Minecraft doesn't need to be decompiled,
* however source files will not be available.
* {@code false} by default.
*/
public boolean isDisableRecompilation() {
return disableRecompilation;
}

public void setDisableRecompilation(boolean disableRecompilation) {
this.disableRecompilation = disableRecompilation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public static ModDevArtifactsWorkflow create(Project project,
ArtifactNamingStrategy artifactNamingStrategy,
Configuration accessTransformers,
Configuration interfaceInjectionData,
VersionCapabilitiesInternal versionCapabilities) {
VersionCapabilitiesInternal versionCapabilities,
boolean disableRecompilation) {
if (project.getExtensions().findByName(EXTENSION_NAME) != null) {
throw new InvalidUserCodeException("You cannot enable modding in the same project twice.");
}
Expand Down Expand Up @@ -141,10 +142,14 @@ public static ModDevArtifactsWorkflow create(Project project,

Function<WorkflowArtifact, Provider<RegularFile>> artifactPathStrategy = artifact -> artifactsBuildDir.map(dir -> dir.file(artifactNamingStrategy.getFilename(artifact)));

task.getCompiledArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.COMPILED));
task.getCompiledWithSourcesArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.COMPILED_WITH_SOURCES));
task.getSourcesArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.SOURCES));
task.getGameJarArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.COMPILED));
task.getResourcesArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.CLIENT_RESOURCES));
if (disableRecompilation) {
task.getDisableRecompilation().set(true);
} else {
task.getGameJarWithSourcesArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.COMPILED_WITH_SOURCES));
task.getGameSourcesArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.SOURCES));
}

task.getNeoForgeArtifact().set(moddingDependencies.neoForgeDependencyNotation());
task.getNeoFormArtifact().set(moddingDependencies.neoFormDependencyNotation());
Expand All @@ -169,10 +174,10 @@ public static ModDevArtifactsWorkflow create(Project project,
// For IntelliJ, we attach a combined sources+classes artifact which enables an "Attach Sources..." link for IJ users
// Otherwise, attaching sources is a pain for IJ users.
Provider<? extends Dependency> minecraftClassesDependency;
if (ideIntegration.shouldUseCombinedSourcesAndClassesArtifact()) {
minecraftClassesDependency = createArtifacts.map(task -> project.files(task.getCompiledWithSourcesArtifact())).map(dependencyFactory::create);
if (!disableRecompilation && ideIntegration.shouldUseCombinedSourcesAndClassesArtifact()) {
minecraftClassesDependency = createArtifacts.map(task -> project.files(task.getGameJarWithSourcesArtifact())).map(dependencyFactory::create);
} else {
minecraftClassesDependency = createArtifacts.map(task -> project.files(task.getCompiledArtifact())).map(dependencyFactory::create);
minecraftClassesDependency = createArtifacts.map(task -> project.files(task.getGameJarArtifact())).map(dependencyFactory::create);
}

// Name of the configuration in which we place the required dependencies to develop mods for use in the runtime-classpath.
Expand Down Expand Up @@ -200,11 +205,11 @@ public static ModDevArtifactsWorkflow create(Project project,
});

// For IDEs that support it, link the source/binary artifacts if we use separated ones
if (!ideIntegration.shouldUseCombinedSourcesAndClassesArtifact()) {
if (!disableRecompilation && !ideIntegration.shouldUseCombinedSourcesAndClassesArtifact()) {
ideIntegration.attachSources(
Map.of(
createArtifacts.get().getCompiledArtifact(),
createArtifacts.get().getSourcesArtifact()));
createArtifacts.get().getGameJarArtifact(),
createArtifacts.get().getGameSourcesArtifact()));
}

var result = new ModDevArtifactsWorkflow(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public void enable(
artifactNamingStrategy,
configurations.getByName(DataFileCollections.CONFIGURATION_ACCESS_TRANSFORMERS),
configurations.getByName(DataFileCollections.CONFIGURATION_INTERFACE_INJECTION_DATA),
versionCapabilities);
versionCapabilities,
settings.isDisableRecompilation());

ModDevRunWorkflow.create(
project,
Expand Down
Loading
Loading