MCME Wiki

MCME-Introduction is the new-player introduction on the hub. A player who joins for the first time passes a welcome room and, if their client needs attention (an unsupported Minecraft version, Forge or OptiFine, or Fabric without MCME's installer), a compatibility room that explains what to do. After the rooms come a welcome title and a series of tips shown as advancement toasts. While a player is in a room, chat from the rest of the network is hidden so the screens can be read. One jar is both the Paper backend plugin and the Velocity proxy plugin. This page describes 1.4.1, the latest release, from MCME/MCME-Introduction.

At a glance

Repository MCME/MCME-Introduction (public, GPL-3.0)
Release branch master (work goes into development through pull requests)
Version described 1.4.1 (tag v1.4.1)
Platform Paper backend plugin (api-version: '26.2') and Velocity proxy plugin, id mcme-introduction (velocity-api 4.2.1-SNAPSHOT plus Velocity proxy internals)
Build Maven, JDK 25 (--release 25)
Depends on Backend: MCME-Architect, ViaVersion, ProtocolLib (hard, depend); MCME-Connect (needed, but not declared). Proxy: VPacketEvents (hard). Optional: MySQL/MariaDB

How the code is organised

src/main/java/com/mcmiddleearth/introduction/
├── paper/
│   ├── IntroductionPlugin       backend entry point: registers the mcme:intro channel, the ProtocolLib
│   │                            chat listener and the /confirm and /intro commands; loads the rooms
│   ├── IntroductionChain        the tips after the rooms: title, start message, broadcast, toasts
│   ├── command/                 ConfirmCommand, IntroCommand (Paper Brigadier commands)
│   ├── confirmData/             ConfirmDataManager and DatabaseConnector: players' /confirm choices
│   ├── flow/                    FlowEvents and FlowLog: the JSON-lines flow log
│   ├── listener/                ChatPacketListener (hides system chat), ConfirmPreLoginListener,
│   │                            GlowListener (glowing item frames), RoomListener (enter, leave, join)
│   └── rooms/                   Room (shared behaviour), FirstRoom (welcome), SecondRoom (compatibility)
└── velocity/
    └── IntroductionPlugin       an empty placeholder; see below
src/main/resources/templates/IntroductionPlugin.java   the real Velocity plugin class

Things to know before you change code:

Building and testing

mvn package

This runs the tests and produces target/MCME-Introduction-<version>-<type>-<commit>.jar. <type> is RELEASE unless you pass -Dbuild.type=DEV.

There is no CI workflow. A release is a pull request from development into master, a vX.Y.Z tag on the merge commit, and a jar built from a plain clone of the tag, attached with its SHA-256 to a GitHub release. The plugin is not published to the Maven repository.

Configuration

Both files live in plugins/MCME-Introduction/ on each backend. The proxy side has no configuration.

Texts are JSON text components in single quotes. Durations are in ticks, except the tip title's times (seconds). /intro reload re-reads both files; database settings and advancement texts need a restart.

Key Shipped value Meaning
supportedVersions ['26.2', '26.3'] Client versions that skip the compatibility room. A version covers every release with the same protocol
joinDelay 11 Ticks after a join before a room, the tips or the reminders start
roomEnterMoveDelay 5 Ticks after entering a room before stepping left counts (a room can override it)
reminderPeriod / reminderDuration 600 / 100 How often the compatibility warning comes back for players who haven't confirmed, and how long it stays
flowLog.enabled / flowLog.keepDays true / 90 The flow log in flow/YYYY-MM-DD.jsonl, and how many days to keep (0: all)
rpMessages.messageRpWarning, messageRpDeclined, messageRpFailedDownload, messageRpFailedReload, messageRpInvalidUrl, messageRpTimeout English texts Resource-pack failure messages; a room can override each
firstRoom.*, secondRoom.* see the reference Fade (tpTransitionTimes, tpTransitionComponent), action bar, toast (advancementKey, advancementDisplay), unsilenceDelay, the screens (cameraOverlay, the four overlayWarning* keys) and the room texts. <supported_versions> in a compatibility message shows the list
introductionChain.* see the reference The welcome title, startMessage, broadcastMessage (must contain _@p_ for the player's name), startBroadcastDelay, initialDelay (600), period (600) and advancementDisplays (one toast per tip)
database.enabled false Store /confirm choices in MySQL/MariaDB (table confirm_data). Without it each server keeps them in memory until it restarts
database.host / port / database / user / password localhost / 3306 / placeholders The database login

locations.yml holds firstRoom and secondRoom (world, pos1, pos2, playerLocation, tpTarget, and for the welcome room an optional displayEntity) and itemGlow (world, pos1, pos2, items, glowColor, rayRange, rayWidth, rayRepetitions, zoom).

docs/configuration.md describes every key, its fallback value and the placeholders.

Data files the plugin writes in its folder: finishedPlayerList.uid (players who finished once, one UUID per line), EnabledGlowItems.dat (players with glowing items on) and the flow log.

Commands and permissions

All commands are on the backend, registered through Paper's Brigadier command API.

Command What it does Who may use it
/intro reload Reload config.yml and locations.yml and rebuild the rooms a second later; reports start, end or failure introduction.reload
/intro glowitem <player> on\|off Turn the glowing item frames on or off for a player the console or another non-player sender only
/confirm optifine Leave the compatibility room and stop its reminders for good players with a Forge-family client on a supported version
/confirm ignore Same, for every other client players /confirm optifine is not for
/confirm reset Forget the player's confirmations players only
Permission Default Grants
------------ --------- --------
introduction.reload op /intro reload

The /confirm subcommands are gated by the player's client, not by permissions.

APIs and extension points

MCME-Introduction offers no API to other plugins. Two outputs are meant for other tools:

How it talks to other plugins and systems

Integrates with Direction How
Its own Velocity half backend → proxy Plugin messages on mcme:intro: a UTF sub-channel enter or exit, then the player's UUID as a UTF string. The backend sends enter when it puts a player in a room and exit when chat comes back
MCME-Architect reads RpManager.getPlayerData(player) for the resource-pack status (a room shows its screen and text once the pack has loaded) and RpManager.isSodiumClient(player) for MCME's marker mod. Architect is the plugin that sends the pack
MCME-Connect reads and writes Listens to PlayerConnectEvent to start a joining player's room, reminders or tips; sends the first-time "just joined" broadcast to the whole network with ConnectUtil.sendMessage(player, "", "", text, 0)
ViaVersion reads Via.getAPI().getPlayerProtocolVersion(player) for the client version
ProtocolLib intercepts A packet listener drops system chat for players in a room, except messages whose root component carries the insertion mcme:intro
VPacketEvents (proxy) intercepts The proxy half drops SystemChatPackets for players a backend reported with enter
MySQL/MariaDB reads and writes Only with database.enabled: true, through the MySQL driver that comes with Paper. Choices are read before the player joins (ConfirmPreLoginListener)
Paper's bukkit datapack writes The room and tip advancements
sequenceDiagram
    participant Px as Velocity proxy (MCME-Introduction)
    participant C as MCME-Connect (backend)
    participant I as MCME-Introduction (backend)
    participant A as MCME-Architect
    C->>I: PlayerConnectEvent (player arrived)
    I->>I: player stands in a room?
    I->>Px: mcme:intro "enter" + UUID
    Px->>Px: drop system chat for this player
    I->>A: RpManager.getPlayerData (pack loaded?)
    I->>I: show the room's screen and text
    Note over I: player steps left, rooms end
    I->>Px: mcme:intro "exit" + UUID
    I->>C: ConnectUtil.sendMessage (first-time broadcast)

The proxy only accepts an enter or exit for the player whose connection carries the message, and it drops a player's silence when they leave the network or arrive on another server, because a backend's exit may never arrive.

System chat is hidden; player chat (/say, /me, signed chat) is not, because since Minecraft 1.21.5 the client disconnects when a numbered player chat message is missing.

Further reading