Skip to content

Commit

Permalink
feat: support Forge and NeoForge (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrrs authored Nov 2, 2024
1 parent 3c23099 commit 5d50c3c
Show file tree
Hide file tree
Showing 21 changed files with 293 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.gradle/
build/
run/
logs/

.idea/
.vscode/
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
[![Modrinth](https://img.shields.io/modrinth/dt/yXAvIk0x?style=flat-square&logo=modrinth)](https://modrinth.com/mod/scribble)
[![CurseForge](https://img.shields.io/curseforge/dt/1051344?style=flat-square&logo=curseforge)](https://curseforge.com/minecraft/mc-mods/scribble)

Read more about it on [Modrinth](https://modrinth.com/mod/scribble) or [CurseForge](https://curseforge.com/minecraft/mc-mods/scribble).
Read more about it on [Modrinth](https://modrinth.com/mod/scribble)
or [CurseForge](https://curseforge.com/minecraft/mc-mods/scribble).

## Project Structure

Scribble supports multiple Minecraft versions using [Stonecutter](https://stonecutter.kikugie.dev/).
The easiest way to interact with this is by using an IDE such as IntelliJ. To switch between versions,
use the Gradle tasks under the `stonecutter` category. Make sure to switch back to `1.21.3` to commit changes.
use the Gradle tasks under the `stonecutter` category. Make sure to switch back to `1.21.3-fabric` to commit changes.

### Release checklist

- Update the version number.
- Change in `gradle.properties`.
- Add an entry in `CHANGELOG.md`.
- Change in `gradle.properties`.
- Add an entry in `CHANGELOG.md`.
- Commit and push a new tag. (example: `v1.2.3`)
- Tag name is the version number prefixed by `v`.
- Tag name is the version number prefixed by `v`.
- Manually trigger the Publish workflow on GitHub.
136 changes: 96 additions & 40 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import me.modmuss50.mpp.ReleaseType

plugins {
id("fabric-loom") version "1.7-SNAPSHOT"
id("dev.architectury.loom") version "1.7-SNAPSHOT"
id("me.modmuss50.mod-publish-plugin") version "0.5.1"
}

fun Project.prop(namespace: String, key: String) =
property("$namespace.$key") as String
fun Project.hasProp(namespace: String, key: String) = hasProperty("$namespace.$key")
fun Project.prop(namespace: String, key: String) = property("$namespace.$key") as String

val minecraftVersion = stonecutter.current.version
val loader = loom.platform.get().name.lowercase()

group = prop("mod", "group")
version = "${prop("mod", "version")}+mc$minecraftVersion"
version = "${prop("mod", "version")}+mc$minecraftVersion-$loader"

if (stonecutter.current.isActive) {
rootProject.tasks.register("runActive") {
group = "project"
dependsOn(tasks.named("runClient"))
}
}

base {
archivesName.set(prop("mod", "name"))
Expand All @@ -20,62 +28,98 @@ base {
loom {
accessWidenerPath = rootProject.file("src/main/resources/scribble.accesswidener")

runConfigs["client"].ideConfigGenerated(true)
runConfigs.forEach { it.ideConfigGenerated(false) }
runConfigs["client"].runDir = "../../run"

runConfigs["server"].ideConfigGenerated(false)
if (loader == "forge") {
forge.mixinConfig("scribble.mixins.json")
}
}

repositories {
maven("https://maven.neoforged.net/releases/")
maven("https://maven.terraformersmc.com/releases/")
maven("https://maven.shedaniel.me/")
}

dependencies {
fun fabricApiModule(name: String) =
modImplementation(fabricApi.module(name, prop("fabric", "apiVersion")))

minecraft("com.mojang:minecraft:$minecraftVersion")
mappings("net.fabricmc:yarn:${prop("fabric", "yarnVersion")}:v2")
modImplementation("net.fabricmc:fabric-loader:${prop("fabric", "loaderVersion")}")

include(fabricApiModule("fabric-resource-loader-v0")!!)
// Yarn mappings
@Suppress("UnstableApiUsage")
mappings(loom.layered {
mappings("net.fabricmc:yarn:${prop("fabric", "yarnVersion")}:v2")

if (hasProp("neoforge", "yarnPatch")) {
mappings("dev.architectury:yarn-mappings-patch-neoforge:${prop("neoforge", "yarnPatch")}")
}
})

// Loader dependencies
when (loader) {
"fabric" -> {
fun fabricApiModule(name: String) =
modImplementation(fabricApi.module(name, prop("fabric", "apiVersion")))

modImplementation("net.fabricmc:fabric-loader:${prop("fabric", "loaderVersion")}")
include(fabricApiModule("fabric-resource-loader-v0")!!)
}

"neoforge" -> "neoForge"("net.neoforged:neoforge:${prop("neoforge", "version")}")
"forge" -> "forge"("net.minecraftforge:forge:${prop("forge", "version")}")
}

modCompileOnlyApi("com.terraformersmc:modmenu:${prop("modmenu", "version")}")
modCompileOnlyApi("me.shedaniel.cloth:cloth-config-fabric:${prop("clothconfig", "version")}")
// Third party mod compat dependencies
if (loader == "fabric") modCompileOnly("com.terraformersmc:modmenu:${prop("modmenu", "version")}")
modCompileOnly("me.shedaniel.cloth:cloth-config-$loader:${prop("clothconfig", "version")}")

// Test dependencies
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.3")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.3")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.3")

testImplementation("org.mockito:mockito-core:5.12.0")
}

// renderButton was changed to renderWidget after 1.20.3
stonecutter.swap("renderWidget") {
val method =
if (stonecutter.compare(minecraftVersion, "1.20.3") >= 0) "renderWidget"
else "renderButton"

"protected void $method(DrawContext context, int mouseX, int mouseY, float delta) {"
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.3")
}

tasks {
processResources {
// We construct our minecraft dependency string based on the versions provided in gradle.properties
val gameVersions = prop("minecraft", "versions").split(",")
val gameVersions = prop("platform", "versions").split(",")
val first = gameVersions.firstOrNull()!!
val last = gameVersions.lastOrNull()!!
val minecraftDependency = if (gameVersions.size == 1) first else ">=$first <=$last"

inputs.property("version", project.version)
filesMatching("fabric.mod.json") {
expand(
"modName" to prop("mod", "name"),
"modVersion" to prop("mod", "version"),
"minecraftDependency" to minecraftDependency
)

// Inject the properties into the mod manifest file
if (loader == "fabric") {
inputs.property("version", project.version)
filesMatching("fabric.mod.json") {
expand(
"modVersion" to prop("mod", "version"),
"minecraftDependency" to if (gameVersions.size == 1) first else ">=$first <=$last"
)
}

exclude("META-INF/mods.toml")
exclude("META-INF/neoforge.mods.toml")
} else if (loader == "forge" || loader == "neoforge") {
filesMatching("META-INF/*mods.toml") {
expand(
"modVersion" to prop("mod", "version"),
"minecraftDependency" to if (gameVersions.size == 1) "[$first]" else "[$first, $last]"
)
}

exclude("fabric.mod.json")

if (loader == "neoforge" && stonecutter.eval(minecraftVersion, ">=1.20.5")) {
exclude("META-INF/mods.toml")
} else {
exclude("META-INF/neoforge.mods.toml")
}
}
}

if (loader == "neoforge" || loader == "forge") {
remapJar {
atAccessWideners.add("scribble.accesswidener")
}
}

Expand All @@ -94,29 +138,41 @@ tasks {
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
val version =
if (stonecutter.eval(minecraftVersion, ">=1.20.6")) JavaVersion.VERSION_21
else JavaVersion.VERSION_17
sourceCompatibility = version
targetCompatibility = version
}

publishMods {
displayName.set("${prop("mod", "version")} - Fabric $minecraftVersion")
val displayLoader = when (loader) {
"forge" -> "Forge"
"fabric" -> "Fabric"
"neoforge" -> "NeoForge"
else -> loader
}

displayName.set("${prop("mod", "version")} - $displayLoader $minecraftVersion")

file.set(tasks.remapJar.get().archiveFile)
changelog.set(providers.environmentVariable("CHANGELOG"))
type.set(if (prop("mod", "version").contains("beta")) ReleaseType.BETA else ReleaseType.STABLE)
modLoaders.addAll("fabric", "quilt")
modLoaders.addAll(prop("platform", "loaders").split(","))

val gameVersions = prop("minecraft", "versions").split(",")
val gameVersions = prop("platform", "versions").split(",")

modrinth {
projectId.set(prop("modrinth", "id"))
accessToken.set(providers.environmentVariable("MODRINTH_TOKEN"))
minecraftVersions.addAll(gameVersions)
optional("cloth-config")
}

curseforge {
projectId.set(prop("curseforge", "id"))
accessToken.set(providers.environmentVariable("CURSEFORGE_TOKEN"))
minecraftVersions.addAll(gameVersions)
optional("cloth-config")
}
}
11 changes: 9 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import dev.kikugie.stonecutter.StonecutterSettings
pluginManagement {
repositories {
maven("https://maven.fabricmc.net/")
maven("https://maven.architectury.dev")
maven("https://maven.neoforged.net/releases/")
maven("https://maven.kikugie.dev/releases")
gradlePluginPortal()
}
Expand All @@ -14,8 +16,13 @@ plugins {

extensions.configure<StonecutterSettings> {
shared {
versions("1.20.1", "1.21", "1.21.3")
vcsVersion = "1.21.3"
fun add(version: String, vararg loaders: String) =
loaders.forEach { vers("$version-$it", version) }

add("1.20.1", "fabric", "forge")
add("1.21", "fabric", "neoforge")
add("1.21.3", "fabric", "neoforge")
vcsVersion = "1.21.3-fabric"
}

kotlinController = true
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/me/chrr/scribble/PlatformEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package me.chrr.scribble;

//? if fabric {

import net.fabricmc.api.ClientModInitializer;

@SuppressWarnings("unused")
public class PlatformEntry implements ClientModInitializer {
@Override
public void onInitializeClient() {
Scribble.init();
}
}
//?} elif neoforge {

/*import me.chrr.scribble.compat.ClothConfigScreenFactory;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.ModList;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
@Mod(value = Scribble.MOD_ID, dist = Dist.CLIENT)
public class PlatformEntry {
public PlatformEntry(ModContainer mod) {
Scribble.init();
if (ModList.get().isLoaded("cloth_config")) {
mod.registerExtensionPoint(IConfigScreenFactory.class,
(container, parent) -> ClothConfigScreenFactory.create(parent));
}
}
}
*///?} elif forge {

/*import me.chrr.scribble.compat.ClothConfigScreenFactory;
import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.loading.FMLLoader;
@Mod(Scribble.MOD_ID)
public class PlatformEntry {
public PlatformEntry() {
Scribble.init();
if (FMLLoader.getDist().isClient() && ModList.get().isLoaded("cloth_config")) {
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class,
() -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> ClothConfigScreenFactory.create(parent)));
}
}
}
*///?}
9 changes: 2 additions & 7 deletions src/main/java/me/chrr/scribble/Scribble.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package me.chrr.scribble;

import me.chrr.scribble.config.ConfigManager;
import net.fabricmc.api.ClientModInitializer;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;

public class Scribble implements ClientModInitializer {
public class Scribble {
public static final String MOD_ID = "scribble";
public static Logger LOGGER = LogManager.getLogger();

public static final ConfigManager CONFIG_MANAGER = new ConfigManager();

@Override
public void onInitializeClient() {
public static void init() {
try {
CONFIG_MANAGER.load();
} catch (IOException e) {
Expand All @@ -28,9 +26,6 @@ public static int getBookScreenYOffset(int screenHeight) {
}

public static Identifier id(String path) {
//? if >=1.21 {
return Identifier.of(MOD_ID, path);
//?} else
/*return new Identifier(MOD_ID, path);*/
}
}
9 changes: 7 additions & 2 deletions src/main/java/me/chrr/scribble/book/FileChooser.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package me.chrr.scribble.book;

import me.chrr.scribble.Scribble;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Language;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
Expand Down Expand Up @@ -61,7 +60,13 @@ public static void chooseBook(boolean save, Consumer<Path> pathConsumer) {
}

public static Path createAndGetBookDirectory() {
Path gameDir = FabricLoader.getInstance().getGameDir();
//? if fabric {
Path gameDir = net.fabricmc.loader.api.FabricLoader.getInstance().getGameDir();
//?} elif neoforge {
/*Path gameDir = net.neoforged.fml.loading.FMLPaths.GAMEDIR.get();
*///?} elif forge
/*Path gameDir = net.minecraftforge.fml.loading.FMLPaths.GAMEDIR.get();*/

Path booksDir = gameDir.resolve("books");

try {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/me/chrr/scribble/compat/ModMenuCompat.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.chrr.scribble.compat;

//? if fabric {
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.fabricmc.loader.api.FabricLoader;
Expand All @@ -13,4 +14,5 @@ public ConfigScreenFactory<?> getModConfigScreenFactory() {
return null;
}
}
}
}
//?}
Loading

0 comments on commit 5d50c3c

Please sign in to comment.