Skip to content

Hello World!

alexstaeding edited this page Mar 7, 2020 · 5 revisions

Let's start writing! This guide will assume that you're using IntelliJ IDEA. Additionally, as stated in creating a project, this guide will follow the development of a plugin called SimpleTickets. Wherever you see that name, just replace it with your project name.

Common module

The first step is to create a new common module.

  1. Right-click your root project directory
  2. New > Module
  3. Select Gradle
  4. Make sure Module SDK is Project SDK (Java 1.8)
  5. Make sure Kotlin DSL build script is disabled
  6. Make sure only java is selected under Additional Libraries and Frameworks
  7. Click next
  8. Set name as common
  9. Click finish

Next, we'll create our first class

  1. In common, open src > main > java
  2. Right-click java > new > Java Class

Type <groupid>.<artifactid>.common.plugin.<artifactid (pascalcase)>. For SimpleTickets, this is

org.anvilpowered.simpletickets.common.plugin.SimpleTickets

In that same package, let's create a class called SimpleTicketsPluginInfo.

Import Anvil

The next step is to tell Gradle which libraries to use. Right now, we want to import anvil-api and anvil-base from Anvil. To do this, your build.gradle (the one inside common) should include the following code:

repositories {
    mavenCentral()
    maven { url 'https://repo.spongepowered.org/maven' }
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}

dependencies {
    implementation 'org.anvilpowered:anvil-api:1.0-SNAPSHOT'
    implementation 'org.anvilpowered:anvil-base:1.0-SNAPSHOT'
    implementation 'com.google.inject:guice:4.1.0'
}

This tells Gradle that we want to use both anvil-api and anvil-base (and guice) in our common module. After we have done this, we can start using classes from those modules in our module. Refresh Gradle by clicking the blue elephant or by going to the Gradle tab on the right and clicking the refresh icon.

Setting up PluginInfo

Implementations of PluginInfo are meant to store the plugin's attributes in public static final fields so that they can be used in annotations too. Below is an (incomplete) example of one such implementation.

public class SimpleTicketsPluginInfo<TString, TCommandSource> implements PluginInfo<TString> {
    public static final String id = "simpletickets";
    public static final String name = "Simple Tickets";
    public static final String version = "$modVersion"; // replaced by blossom from gradle
    public static final String description = "A simple ticket plugin";
    public static final String url = "https://github.com/AnvilPowered/SimpleTickets";
    public static final String[] authors = {"Cableguy20"};
    public static final String organizationName = "AnvilPowered";
    public static final String buildDate = "$buildDate";  // replaced by blossom from gradle
    public TString pluginPrefix;

    @Inject
    public void setPluginPrefix(TextService<TString, TCommandSource> textService) {
        pluginPrefix = textService.builder()
            .blue().append("[")
            .aqua().append(name)
            .blue().append("] ") // space at the end to make it easier to append text later
            .build();
    }

... getters and setters not included ...

Extending BasePlugin

The next step is to extend the BasePlugin class. Make sure to define your own type parameter to pass along to BasePlugin. It should look something like this:

public abstract class SimpleTickets<TPluginContainer> extends BasePlugin<TPluginContainer> {

    protected SimpleTickets(Injector injector) {
        super(SimpleTicketsPluginInfo.id, injector);
    }
}

Sponge Module

Create a sponge module exactly the same way you created the common module. This time, the build.gradle (in the sponge module) should include the following code:

plugins {
    id 'java'
    id 'com.github.johnrengelman.shadow'
    id 'org.spongepowered.plugin' version '0.9.0'
}

repositories {
    mavenCentral()
    maven { url 'https://repo.spongepowered.org/maven' }
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}

dependencies {
    implementation project(':common')
    implementation 'org.anvilpowered:anvil-api:1.0-SNAPSHOT'
    implementation 'org.anvilpowered:anvil-base:1.0-SNAPSHOT'
    implementation 'com.google.inject:guice:4.1.0'
    compileOnly('org.spongepowered:spongeapi:7.2.0-SNAPSHOT') {
        exclude(module: 'configurate-gson')
        exclude(module: 'configurate-yaml')
    }
    annotationProcessor 'org.spongepowered:spongeapi:7.2.0-SNAPSHOT'
}

We're now going to create a class with the package and name format, <groupid>.<artifactid>.sponge.plugin.<artifactid (pascalcase)>Sponge. For SimpleTickets this is:

org.anvilpowered.simpletickets.sponge.plugin.SimpleTicketsSponge

This class will serve as the sponge version of our main class. It should look like:

@Plugin(
    id = SimpleTicketsPluginInfo.id,
    name = SimpleTicketsPluginInfo.name,
    version = SimpleTicketsPluginInfo.version,
    dependencies = @Dependency(id = "anvil"),
    description = SimpleTicketsPluginInfo.description,
    url = SimpleTicketsPluginInfo.url,
    authors = "Cableguy20"
)
public class SimpleTicketsSponge extends SimpleTickets<PluginContainer> {

    @Inject
    public SimpleTicketsSponge(Injector injector) {
        super(injector);
    }
}