[Resource] Using Mill in Sponge plugin development

Hello,
This is a presentation of The Mill build tool and how to use it with Sponge.

Note: I’m not sure it’s the best place for this article but it seems logical to me to post it here
Note 2: I’m French so my post might contain some english mistakes

What is Mill ?

BuildScript and Mill’s DSL

Mill is a Java and Scala build tool like Gradle. While Gradle uses a Groovy/Kotlin DSL, Mill uses a Scala one organized in a build.sc file like this:

object myModule extends JavaModule {

  def ivyDeps = Agg.empty //Include your required dependencies here
}

For Scala projects:

object myModule extends ScalaModule {

  def scalaVersion = "2.13.4"

  def ivyDeps = Agg.empty
}

As you can see, Mill’s DSL is a bit lighter than Gradle. It is also faster than Gradle for subsequent builds.

The task system

Like Gradle, Bazel, Ivy and many other build tools, Mill have a task system:

mill module.task

For example we can build a fatJar using the assembly task:

mill myModuleName.assembly

To execute all tasks of a module or execute a specific task of all modules you can use _:

mill _.compile

compiles all modules.

You can search for tasks using resolve:

mill resolve _.compile

shows all tasks named compile in all modules.

More informations here

REPL

Mill uses the Scala’s REPL (Ammonite) to allows the use to easily navigate thought the build without modifying the script. You can simply enable it by using the --repl flag:

mill --repl

Using Mill for Sponge development

We can use Mill’s DSL to create a plugin to facilitate Sponge development. That’s why I created MCMill.

MCMill is a Mill plugin for Sponge plugin development like the official SpongeGradle.

To use MCMill, we will just use an “ivy” import:

import mill._, scalalib._ //Mill base imports
import $ivy.`io.github.iltotore::mcmill-sponge:0.0.2` //import $ivy imports an Ivy/Maven dependency in the buildscript classpath
import io.github.iltotore.mcmill.sponge._ //We import the root package of MCMill-Sponge. Consider the underscore as Java's "*"

object myModule extends JavaModule with SpongeModule { //This is called "trait mixin". In short way, it's like implementing multiples interfaces in Java

  def spongeVersion = "7.3.0"

  def spongeMetadata = SpongeMetadata( //Metadata for mcmod.info. All attributes are supported.
    modId = "my-plugin",
    name = "MyPlugin",
    version = "0.1",
    description = "This is a simple MCMill test for Sponge",
    authors = Seq("Il_totore")
  )
}

This is simple configuration allows you to do three things:

  • Import the Sponge API with the desired version
  • Generate the mcmod.info file from the spongeMetadata field/method using the generateModInfo task
  • Build a valid plugin jar using the spongeJar task

Done.
This a sample of what I wanted to share with you. I invite you to test Mill and build you own opinion about this build tool.

Note: if you want to use Mill with your IDE like Intellij IDEA, I suggest you to use the Mill BSP support

If you have any problem, feel free to ask on:

  • this thread
  • MCMill’s issue section
  • Mill’s issue section (only for true issues) or gitter

Bye !

Very cool! What’s the sort of dependency hooks that are available to possibly providing a full blown development environment for plugin developers gaining a runnable SpongeVanilla/SpongeForge client locally?

Hello, sorry for the delay @gabizou !
Mill supports ivy, maven and module dependencies but it’s pretty easy to add other dependencies type.