Project setup
The fastest way to start is the ExampleModule template. On GitHub, select
“Use this template” to create your own repository from it, then clone that repository. It ships the Gradle files, a
module.yml, and an example command and listener, so you can build it right away and change it to fit your module.
To adapt the template, change the project name in settings.gradle.kts, the archiveBaseName in build.gradle.kts, and
the fields in module.yml. The sections below explain each of these files. You can also read the source of an official
module, such as Module-NUSH or
Module-FalseOp, for a larger working example.
settings.gradle.kts
Section titled “settings.gradle.kts”Set the project name. All official modules use the name format Module-<name>.
rootProject.name = "Module-Example"build.gradle.kts
Section titled “build.gradle.kts”Plex runs on Java 25, so set the Java toolchain to 25. Add the Paper API and the Plex API as compileOnly
dependencies. Plex provides both at runtime, so you must not shade them into your JAR.
plugins { java `maven-publish`}
repositories { maven { url = uri("https://repo.papermc.io/repository/maven-public/") } maven { url = uri("https://nexus.telesphoreo.me/repository/plex/") } mavenCentral()}
dependencies { compileOnly("io.papermc.paper:paper-api:26.1.2.build.+") compileOnly("dev.plex:api:2.0-SNAPSHOT")}
group = "dev.plex"version = "2.0-SNAPSHOT"description = "Module-Example"
java { toolchain.languageVersion.set(JavaLanguageVersion.of(25))}
tasks.getByName<Jar>("jar") { archiveBaseName.set("Module-Example") archiveVersion.set("")}The archiveBaseName sets the name of your JAR file. Keep the Module- prefix. The archiveVersion.set("") call removes
the version from the file name, so the built file is Module-Example.jar. A stable file name lets the module updater
replace the JAR in place. The ExampleModule template also includes Lombok and a Maven publishing block, which you can keep
or remove.
Build the project once with Gradle to confirm that everything resolves.
The module descriptor
Section titled “The module descriptor”Create src/main/resources/module.yml. Plex reads this file to load your module.
name: Module-Examplemain: dev.plex.ExampleModuledescription: An example module for Plexversion: 2.0-SNAPSHOTapiCompatibility: 1The fields are as follows.
| Field | Required | Description |
|---|---|---|
name |
Yes | The module name. Plex uses it for the data folder and for /plex modules commands. |
main |
Yes | The full class name of your main module class. |
description |
No | A short description. The default is A Plex module. |
version |
No | The module version. The default is 1.0. |
apiCompatibility |
Yes | The Plex API version that your module needs. This must be an integer. |
The apiCompatibility value must match the API version of the Plex build that loads the module. Plex provides API
version 1. If the numbers do not match, Plex skips the module and writes a warning to the console. When the module API
changes in a way that breaks modules, this number increases, and a module must set the new value to match.
Two optional blocks control extra libraries and the updater. See Libraries and storage and Build and install.
The main class
Section titled “The main class”Your main class extends PlexModule. Register your commands and listeners in enable(). Pass this to a command or
listener that needs the module, so it can reach api() and your config.
package dev.plex;
import dev.plex.command.ExampleCommand;import dev.plex.listener.ExampleListener;import dev.plex.module.PlexModule;
public class ExampleModule extends PlexModule{ @Override public void enable() { registerCommand(new ExampleCommand()); registerListener(new ExampleListener(this)); api().logging().info("{0} enabled with Plex API compatibility {1}", getPlexModuleFile().getName(), api().compatibility().version()); }
@Override public void disable() { // Unregistering listeners / commands is handled by Plex }}PlexModule also gives you these helper methods.
| Method | Description |
|---|---|
api() |
Returns the Plex API facade. |
registerCommand(PlexCommand) |
Registers a command owned by this module. |
registerListener(Listener) |
Registers a listener owned by this module. |
unregisterCommand(PlexCommand) / unregisterListener(Listener) |
Removes a command or listener. |
getDataFolder() |
Returns the module data folder, plugins/Plex/modules/<name>/. |
getLogger() |
Returns the module logger. |
getResource(String) |
Opens a file from the module JAR. |
loadMessages(String) |
Loads the module message file. See Messages. |
Plex removes tracked commands and listeners for you when the module disables. You only need disable() for resources that
Plex does not track, such as an external connection or a third-party listener.
