mcNows

Generate example

Generate a small starter Nows mod project.

Generated Gradle files use https://files.nows.space/maven/. The Nows plugin applies Java, prepares Minecraft and adds the normal compile-only classpath.

settings.gradle.kts
pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
        maven("https://repo.spongepowered.org/repository/maven-public/")
        maven("https://files.nows.space/maven/")
    }
}

rootProject.name = "my_mod"
gradle.properties
org.gradle.jvmargs=-Xmx2G -Dfile.encoding=UTF-8
org.gradle.parallel=true

minecraft_version=26.2
nows_version=0.6.2

mod_id=my_mod
mod_name=My Mod
mod_version=1.0.0
mod_description=My Mod generated starter mod.
mod_author=
mod_license=Apache-2.0
mod_icon=
mod_homepage=
mod_sources=
mod_issues=
build.gradle.kts
plugins {
    id("java")
    id("space.nows.mcnows") version "0.6.2"
}

group = "com.example.mymod"
version = providers.gradleProperty("mod_version").get()

val configuredMinecraftVersion = providers.gradleProperty("minecraft_version")
val configuredNowsVersion = providers.gradleProperty("nows_version")
val modProperties = mapOf(
    "modId" to providers.gradleProperty("mod_id").get(),
    "modName" to providers.gradleProperty("mod_name").get(),
    "modVersion" to providers.gradleProperty("mod_version").get(),
    "modDescription" to providers.gradleProperty("mod_description").get(),
    "modAuthor" to providers.gradleProperty("mod_author").get(),
    "modLicense" to providers.gradleProperty("mod_license").get(),
    "modIcon" to providers.gradleProperty("mod_icon").get(),
    "modHomepage" to providers.gradleProperty("mod_homepage").get(),
    "modSources" to providers.gradleProperty("mod_sources").get(),
    "modIssues" to providers.gradleProperty("mod_issues").get(),
)

repositories {
    mavenCentral()
    maven("https://repo.spongepowered.org/repository/maven-public/")
    maven("https://files.nows.space/maven/")
}

nows {
    minecraftVersion.set(configuredMinecraftVersion)
    nowsVersion.set(configuredNowsVersion)
    expandNowsModMetadata.set(false)
}

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

tasks.withType<JavaCompile>().configureEach {
    options.encoding = "UTF-8"
    options.release.set(17)
}

tasks.jar {
    archiveBaseName.set(providers.gradleProperty("mod_id"))
}

tasks.processResources {
    inputs.properties(modProperties)
    inputs.property("minecraftVersion", configuredMinecraftVersion)
    inputs.property("nowsVersion", configuredNowsVersion)
    filesMatching("nows.mod.kdl") {
        expand(
            modProperties + mapOf(
                "minecraftVersion" to configuredMinecraftVersion.get(),
                "nowsVersion" to configuredNowsVersion.get(),
            ),
        )
    }
}

fun defaultMinecraftModsDir(): String {
    val os = System.getProperty("os.name").lowercase()
    val home = System.getProperty("user.home")
    return when {
        os.contains("win") -> (System.getenv("APPDATA") ?: "$home/AppData/Roaming") + "/.minecraft/mods"
        os.contains("mac") -> "$home/Library/Application Support/minecraft/mods"
        else -> "$home/.minecraft/mods"
    }
}

val minecraftModsDir = providers.gradleProperty("minecraft_mods_dir")
    .orElse(defaultMinecraftModsDir())

tasks.register<Copy>("installMod") {
    group = "nows"
    description = "Builds the mod jar and copies it to the Minecraft mods directory."
    dependsOn(tasks.jar)
    from(tasks.jar)
    into(minecraftModsDir)
}
README.md
# My Mod

Generated Nows mod project.

## Build

```bash
gradle build
```

The Nows Gradle plugin prepares the selected Minecraft client jar, adds the matching
`nows-mc-26.2` adapter, expands `nows.mod.kdl`, and builds the mod jar.

## Install And Run

Install the Nows launcher profile for Minecraft 26.2 / Nows 0.6.2, then run:

```bash
gradle installMod
```

`installMod` copies `build/libs/my_mod-<mod_version>.jar` to the default Minecraft
`mods` folder. To target another folder:

```bash
gradle installMod -Pminecraft_mods_dir=/path/to/.minecraft/mods
```

Open the Nows profile in the Minecraft Launcher and start the game.
src/main/resources/nows.mod.kdl
mod id="${modId}" name="${modName}" version="${modVersion}" minecraft="${minecraftVersion}" side="client" {
    info {
        description "${modDescription}"
        author "${modAuthor}"
        license "${modLicense}"
        icon "${modIcon}"
    }

    links {
        homepage "${modHomepage}"
        sources "${modSources}"
        issues "${modIssues}"
    }

    compatibility {
        requires "minecraft" version="${minecraftVersion}"
        requires "nows" version="${nowsVersion}"
    }

    runtime {
        entrypoint "com.example.mymod.MyMod"
        mixin "my_mod.mixins.json"
        listener "com.example.mymod.MyModLifecycleListener"
    }
}
src/main/resources/assets/my_mod/lang/en_us.json
{
  "itemGroup.my_mod.main": "My Mod",
  "screen.my_mod.config": "My Mod Settings",
  "option.my_mod.enabled": "Enabled",
  "option.my_mod.cooldown": "Cooldown"
}
src/main/resources/my_mod.mixins.json
{
  "required": false,
  "package": "com.example.mymod.mixin",
  "compatibilityLevel": "JAVA_25",
  "mixins": [],
  "client": []
}
src/main/java/com/example/mymod/MyMod.java
package com.example.mymod;

import reactor.util.Logger;
import space.nows.mcnows.api.ModInitializer;
import space.nows.mcnows.api.NowsContext;
import space.nows.mcnows.integration.logging.NowsLog;

public final class MyMod implements ModInitializer {
    private static final Logger LOG = NowsLog.get(MyMod.class);

    @Override
    public void onInitialize(NowsContext context) {
        LOG.info("My Mod loaded on {} with {} mod(s).",
                context.side().metadataName(), context.mods().size());
    }
}
src/main/java/com/example/mymod/MyModLifecycleListener.java
package com.example.mymod;

import reactor.util.Logger;
import space.nows.mcnows.integration.geb.NowsLifecycleListener;
import space.nows.mcnows.integration.geb.event.NowsEntrypointsCompletedEvent;
import space.nows.mcnows.integration.logging.NowsLog;

public final class MyModLifecycleListener implements NowsLifecycleListener {
    private static final Logger LOG = NowsLog.get(MyModLifecycleListener.class);

    @Override
    public void onNowsEntrypointsCompleted(NowsEntrypointsCompletedEvent event) {
        LOG.info("My Mod observed {} entrypoint(s).", event.count());
    }
}
.gitignore
.gradle/
build/
out/
*.iml