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.
- Repository: github.com/MCME/MCME-Base (the 2.x code is on the
developmentbranch; see Branches and releases) - Artifact:
com.mcmiddleearth:mcme-baseon the Maven repository
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.
- Do not pin Adventure in your own build. It comes from paper-api and velocity-api at the platform's version; an explicit Adventure dependency can pull in an older version and break compilation (for example,
PlayerHeadObjectContentsgoes missing). - Build with JDK 25. mcme-base 2.x is Java 25 bytecode.
- Use 2.0.1, not 2.0.0. 2.0.1 fixes a file handle that
YamlConfiguration(File)left open, which on Windows blocks deleting the file and on Linux leaks one handle per configuration loaded.
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:
- on a push to
developmentwith a-SNAPSHOTversion, publishes the snapshot to thesnapshotsrepository; - on a
v*tag, checks that the tag equalsvplus the pom version, publishes the release toreleases, and creates the GitHub Release with the jar attached.
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
- The bundled
velocity-plugin.jsonhas a fixed"version":"1.0-SNAPSHOT", so Velocity lists MCME-Base with that version whatever the jar is. Check the jar name or the Paper side (plugin.ymltakes the pom version) to see which release is installed. - The README at
v2.0.1still shows2.0.0in its dependency snippet and says no extra repositories are needed; the snippet above is the current one.