MCME Wiki

PluginUtils is MCME's shared helper library for Paper plugins: chat messages with clickable parts, confirmation prompts, regions, a plot storage format, thin access to server internals, and small helpers for WorldEdit and Dynmap. It runs on the server as a plugin of its own, and other plugins compile against it and declare it as a dependency; they never bundle it. The current line is 2.0.x for Paper 26.2, and the latest release is 2.0.6.

What is in it

All classes are under com.mcmiddleearth.pluginutil.

Package What it gives you
message FancyMessage (chat lines with click and hover actions), MessageUtil, JSON message parsing, config-driven message templates (FancyMessageConfigUtil). Since 2.0.5 messages are sent as Adventure components, so clicks and tooltips work on 26.2, and paged lists end with a [‹ Prev] Page 2/3 [Next ›] line
confirmation Chat confirmation prompts (ConfirmationFactory, ConfirmationPrompt)
region Region maths: CuboidRegion, PrismoidRegion, SphericalRegion, with WorldEdit interop
plotStoring The MCME plot format (MCMEPlotFormat, IStoragePlot, StoragePlotSnapshot): save and restore block regions with block entities, biomes and entities as compact NBT. MCME-Architect's copy and paste uses it
nms Thin access to server internals (AccessNBT, AccessWorld, AccessServer, AccessInventory, NBTTagBuilder, ...), compiled against Paper's mojang-mapped dev bundle
developer DevUtil, Debugable and the /dev command for per-plugin debug output
top level BlockUtil, EntityUtil, PlayerUtil, StringUtil, NumericUtil, FileUtil, JSONUtil, TitleUtil, ConfigurationUtil, ReflectionUtil, LegacyMaterialUtil (pre-1.13 id and data to BlockData), WEUtil (WorldEdit), DynmapUtil (Dynmap)

The plugin itself

The PluginUtils jar is a plugin (load: STARTUP) with one command:

Command Permission Default What it does
/dev <plugin> [true \| false \| <level> \| r] pluginutil.developer op Sends a plugin's debug output to you in chat, or to the console

It soft-depends on ProtocolLib, Essentials, WorldEdit and dynmap. It has no config file.

Using it in a plugin

Compile against it, declare it in plugin.yml, and let the server provide it. Do not shade it.

Gradle

repositories {
    maven { url = 'https://repo.mcmiddleearth.com/releases' }
}
dependencies {
    compileOnly 'com.mcmiddleearth:PluginUtils:2.0.6'
    // Only if your tests load PluginUtils classes (for example with MockBukkit):
    testImplementation 'com.mcmiddleearth:PluginUtils:2.0.6'
}

Maven

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

<dependency>
    <groupId>com.mcmiddleearth</groupId>
    <artifactId>PluginUtils</artifactId>
    <version>2.0.6</version>
    <scope>provided</scope>
</dependency>

plugin.yml

depend: [PluginUtils]

Things to know:

Building

./gradlew build

The build uses paperweight-userdev, which resolves paper-api and the server's internal classes from PaperMC's published dev bundle (26.2.build.111-stable). There is no local server jar to place by hand, so it builds on any machine and in CI. The first build downloads and decompiles the Paper server, which takes a few minutes; later builds use the cache. The jar lands in build/libs/.

CI (.github/workflows/build.yml) builds every push to master and development, every pull request and every tag, on ubuntu-26.04 with Temurin 25.

Branches and releases

Branch What it holds
master Releases, 2.0.x. It moves only when a version is released, through a pull request from development
development Where the work happens, through pull requests
pluginutils-26.2, publish-2.0.2, 1.13 History: where 2.0.x was ported, where 2.0.2 was published from, and a 2018 branch

Both master and development are protected. The legacy 1.9.x line (Paper 1.21.x, a Maven build that needed a local server jar) ends at commit f17ced6.

To release (from the README):

  1. On a branch from development, set version in build.gradle, move the [Unreleased] notes in CHANGELOG.md into a dated section, and update the version in the README. Commit it as release: PluginUtils X.Y.Z — <what changed> and open a pull request into development.
  2. When CI is green and the pull request is merged, tag the release commit with an annotated, bare tag (2.0.6, not v2.0.6) and push it. CI then publishes that version to the Maven repository. releases refuses to overwrite a version, so check the published POM, module and jar afterwards.
  3. Open a pull request from development into master.
  4. On development, start the next version: version = 'X.Y.(Z+1)-SNAPSHOT'.

Release history (2.0.x)

Version Date What changed
2.0.0 2026-08-11 Withdrawn: the jar's plugin.yml had an unfilled name and Paper refused to load it
2.0.1 2026-08-11 Fills in the plugin.yml tokens
2.0.2 2026-08-11 Built against Paper 26.2 instead of 26.1.2; the first release that works on 26.2
2.0.3 2026-09-21 Registers the /dev permission, fixes the dynmap soft dependency and other plugin.yml keys Paper ignored
2.0.4 2026-09-23 No code changes: json-simple is declared in the published POM and module, so consumers' MockBukkit tests find it
2.0.5 2026-10-02 Messages as Adventure components (clicks and tooltips work again on 26.2); new list pager line; first tests
2.0.6 2026-10-23 Hover text wraps words too long for one line; jars built on Windows and in CI are identical

CHANGELOG.md has the full notes.