MCME Wiki

MCME-Base (artifact mcme-base) is a shared library that lets a plugin's logic run on both the Paper game servers and the Velocity proxy. It wraps the parts a plugin usually needs (players, servers, messages, commands, scheduling, permissions, configuration, logging, scoreboards) in one platform-neutral API, with an implementation for each platform. Like PluginUtils, it is installed as a plugin of its own, and the plugins that use it compile against it without bundling it. The latest release is 2.0.1; its main user is MCME-Connect.

What it provides

Package What it holds
com.mcmiddleearth.base.core The platform-neutral API: players (McmePlayer, McmeProxyPlayer, McmeBackendPlayer), servers (McmeServer, McmeServerInfo, McmeProxy, McmeBackend), messages (Message, McmeColors, click and hover events), a Brigadier-based command framework (command/: argument types, builders, nodes, handlers), task scheduling, permissions, YamlConfiguration, logging, scoreboards and plugin-message types (MessageToBackend, MessageToProxy)
com.mcmiddleearth.base.bukkit The Paper implementation, with AbstractPaperPlugin as the base class for a Paper plugin
com.mcmiddleearth.base.velocity The Velocity implementation, with AbstractVelocityPlugin as the base class for a Velocity plugin
com.mcmiddleearth.base.adventure Adventure helpers (AdventureMessage, AdventureUtils)

A plugin writes its logic against core and uses the bukkit or velocity implementation for the platform it runs on.

Building a plugin on it

On Paper, extend AbstractPaperPlugin instead of JavaPlugin, and implement enable() and disable(). The base class owns onEnable() and onDisable() (they are final) and gives you getMcmeBackend(), getMcmeLogger() and getTask(Runnable). Declare the dependency in plugin.yml:

depend: [MCME-Base]

On Velocity, extend AbstractVelocityPlugin, pass Velocity's injected logger, proxy server and data directory to its constructor, and implement enable() and disable(). The base class subscribes to the proxy's start and shutdown events for you. Declare the dependency on the plugin id mcme-base. MCME-Connect does it like this:

@Plugin(id = "mcmeconnect", name = "MCME-Connect", version = "3.1.1",
        dependencies = {@Dependency(id = "mcme-base")})
public class ConnectVelocityPlugin extends AbstractVelocityPlugin {

    @Inject   // com.google.inject.Inject
    public ConnectVelocityPlugin(Logger logger, ProxyServer proxyServer,
                                 @DataDirectory Path dataDirectory) {
        super(logger, proxyServer, dataDirectory);
    }
    ...
}

Using it as a dependency

<repositories>
    <repository>
        <id>mcme-releases</id>
        <url>https://repo.mcmiddleearth.com/releases</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.mcmiddleearth</groupId>
    <artifactId>mcme-base</artifactId>
    <version>2.0.1</version>
    <scope>provided</scope>
</dependency>

The mcme-base jar must be installed on every server and proxy that runs a plugin built on it.

Building

mvn -B -ntp verify      # what CI runs
mvn install             # to put a local build in ~/.m2
Java 25 (<release>25</release>)
Build Maven, no shade plugin
Compiled against paper-api 26.1.2.build.72-stable, velocity-api 3.4.0-SNAPSHOT (both provided)
Repositories MCME's mirror first, then PaperMC and Sonatype
Tests none

Bungee and Waterfall support was removed in 2.0.0: MCME runs Paper and Velocity only.

Branches and releases

Branch or tag What it holds
development The 2.x line. Now at 2.0.2-SNAPSHOT
v2.0.0, v2.0.1 The releases, tagged on development
master The old 1.x line (1.0-SNAPSHOT-waterfall-fix-1.21). It is not where releases come from

Both branches are protected. The CI workflow (.github/workflows/build.yml) builds every push and pull request, then:

So a release is: set the release version in pom.xml, push the commit to development through a pull request, push an annotated vX.Y.Z tag on it, then move development on to the next -SNAPSHOT.

Known quirks