MCME Wiki

MCME is one Minecraft network. Players connect to a Velocity proxy, which passes them on to several Paper game servers (the "backends"). Around the game sit a live map, the websites, a Maven repository for our own libraries and a Discord bot. This page shows how that code connects: which plugin depends on which, which messages travel between the proxy and the game servers, and what the web pieces read. It does not cover machines, hosts or which plugin runs on which server; that is in Network topology (operators only).

Every plugin named here has its own page under Developers. Start there for build steps, config and commands.

The game network

Several MCME plugins come in two halves: one runs on the Velocity proxy, the other on the Paper servers. The halves talk over plugin channels: named message channels that Minecraft carries over the player's connection between the proxy and a backend. A plugin message needs a player online on that backend to travel.

graph LR
  subgraph proxy["Velocity proxy"]
    CP["MCME-Connect"]
    WV["MCME-Warps (Velocity half)"]
    GV["thegaffer-velocity"]
    IV["MCME-Introduction (proxy half)"]
    TV["WebTeleport (Velocity)"]
    AV["AccountLink (Velocity)"]
  end
  subgraph paper["Paper servers"]
    CB["MCME-Connect"]
    WP["MCME-Warps (Paper half)"]
    GP["TheGaffer"]
    IP["MCME-Introduction"]
    TP["WebTeleport (Paper)"]
  end
  CB ---|"mcme:connect"| CP
  WP ---|"mcme:warp, mcme:player-location, mcme:misc"| WV
  GP ---|"mcme:gaffer"| GV
  IP -->|"mcme:intro"| IV
  TV -->|"mcme:webteleport"| TP

Not every Paper server runs every plugin. The table lists what each channel carries.

Channel Between What it carries
mcme:connect MCME-Connect on the proxy and on each backend One channel for everything: the first string in a message names the operation (server switching, teleports, cross-server chat, titles, commands, restarts, statistics). Constants in com.mcmiddleearth.connect.Channel
mcme:warp, mcme:player-location, mcme:misc The Velocity and Paper halves of MCME-Warps Warp requests and where to place the player. The two halves must run the same version
mcme:gaffer TheGaffer and thegaffer-velocity The network-wide job list: JOB_CREATED, JOB_DELETED, JOB_SYNC. Each backend restates its jobs when a player joins, because a backend cannot send a plugin message before a player is connected
mcme:intro MCME-Introduction, backend to proxy enter / exit plus the player's UUID, so the proxy knows who is inside an introduction room
mcme:webteleport WebTeleport, Velocity to Paper Where to teleport a player who clicked on the map; the Paper side lands them at surface height
BungeeCord A backend plugin and the proxy's built-in forwarding (Velocity understands this BungeeCord-era channel) Messages to other servers or players without a proxy plugin of your own. TheGaffer uses it for its older network-wide job announcement (with proxyAnnouncesJobs: true the proxy plugin announces jobs instead); CommonerVote uses it to send vote updates to other servers

Who builds against whom

MCME plugins compile against each other's published jars, which come from the Maven repository. None of them bundles (shades) another MCME plugin or library: the dependency must be installed on the server as its own plugin.

graph TB
  BASE["MCME-Base"]
  PU["PluginUtils"]
  CON["MCME-Connect"]
  ARCH["MCME-Architect"]
  INTRO["MCME-Introduction"]
  PVP["MCME-PvP"]
  GB["Guidebook"]
  GAF["TheGaffer"]
  CON --> BASE
  CON --> PU
  ARCH --> PU
  ARCH --> CON
  INTRO --> ARCH
  INTRO --> CON
  PVP --> PU
  GB --> PU
  ARCH -.->|"reflection, by method name"| GAF

Solid arrows are Maven or Gradle dependencies; the dotted arrow is a runtime call without a compile-time dependency.

Plugin Compiles against (MCME artifacts, release branch) plugin.yml Also talks to
MCME-Architect PluginUtils 2.0.4, MCME-Connect 3.0.1 depend: [PluginUtils]; softdepends ProtocolLib, Essentials, dynmap, ViaVersion, MCME-Connect TheGaffer (job protection), Dynmap (map layers), ResourcePackScripts (/rp release)
MCME-Connect MCME-Base 2.0.1, PluginUtils 2.0.2 depend: [MCME-Base]; softdepends PremiumVanish, DiscordSRV, PluginUtils, Multiverse-Core LuckPerms, DiscordSRV (join and leave messages), a MySQL/MariaDB database (statistics)
MCME-Introduction MCME-Architect 3.1.0, MCME-Connect 3.0.3 depend: [MCME-Architect, ViaVersion, ProtocolLib] Architect's resource-pack API (RpManager); Connect's PlayerConnectEvent and ConnectUtil.sendMessage (used, but not declared in plugin.yml)
TheGaffer none (its own thegaffer-core module) softdepends DiscordSRV, MCME-Connect, dynmap DiscordSRV (job announcements)
MCME-PvP PluginUtils 2.0.4 depend: [WorldEdit, PlaceholderAPI, PluginUtils]
Guidebook PluginUtils 2.0.4 depend: [WorldEdit, PluginUtils]; softdepends Multiverse-Core, dynmap
MCME-Warps none softdepends dynmap Dynmap (warp layer)
CommonerVote none depend: [LuckPerms] Other servers, through the proxy's BungeeCord channel; a MySQL/MariaDB database

Perks and RankBoard are in private repositories; their pages describe them.

TheGaffer's build-protection API

MCME-Architect asks TheGaffer whether a player may build before its tools act, and tells TheGaffer about blocks it places so they count towards the player's job. There is no compile-time dependency: Architect looks up three static methods on com.mcmiddleearth.thegaffer.TheGaffer by name.

Method Returns
hasBuildPermission(Player, Location) boolean: may the player build there
getBuildProtectionMessage(Player, Location) String: the reason to show when the answer is no
recordExternalBuild(Player, Location, boolean place) void: counts one placed (true) or broken block towards the player's job (TheGaffer 3.0.0 and later)

Because the lookup is by name, renaming or changing one of these methods does not break the build: it silently switches off Architect's job checks. Treat the three signatures as a contract and change both repositories together. TheGaffer's ProtectionApiContractTest pins them.

Around the game

graph LR
  DYN["Dynmap on the Paper servers"]
  ARCH["MCME-Architect"]
  WARP["MCME-Warps"]
  MAP["LiveAtlas map"]
  WT["WebTeleport (Velocity)"]
  AV["AccountLink (Velocity) /mcmeverify"]
  BOT["Discord bot (qBot)"]
  PERKS["Perks"]
  FORUM["Forum and its Pledge system"]
  FRONT["Front page"]
  RPS["ResourcePackScripts release automation"]
  GH["GitHub releases"]
  CI["GitHub Actions"]
  MVN["Maven repository"]
  ARCH -->|"marker layers"| DYN
  WARP -->|"warp layer"| DYN
  DYN -->|"tiles and JSON files"| MAP
  MAP -->|"teleport requests"| WT
  AV -->|"link codes"| BOT
  PERKS -->|"linked accounts, Patreon data"| BOT
  PERKS -->|"Pledge totals"| FORUM
  FRONT -->|"reads"| FORUM
  ARCH -->|"/rp release runs"| RPS
  RPS -->|"pack zips"| GH
  CI -->|"publishes jars"| MVN

When you add a connection