Skip to content

Creating MiniModes Extensions

MiniModes is designed so that games live outside the core plugin as extensions.
This page gives you a high‑level, implementation‑oriented overview of what that means and how to approach building your own game.

If you already build Spigot/Paper plugins, you’ll feel at home: MiniModes handles parties, worlds, game flow, and GUIs so you can focus on game logic.


A MiniModes extension is:

  • A self‑contained package (distributed as a .mmx file)
  • Loaded by the ExtensionLoader in the core plugin
  • Described by metadata (name, description, player counts, icon, flags)
  • One or more game classes that implement the MiniModes game API

From MiniModes’ point of view, an extension answers:

“What games do you provide, which parties can play them, and how do they run?”

You don’t fork or touch the core plugin to add a new game.
You just drop a new extension into the MiniModes extensions folder, and it shows up in /minimodes.


Mental model: your game inside the MiniModes engine

Section titled “Mental model: your game inside the MiniModes engine”

MiniModes gives you a set of engine services so your game doesn’t have to reinvent them:

  • GameManager
    Starts/stops your game instance, tracks who’s playing, and wires it into the rest of the system.

  • PartyManager
    Ensures your game always runs for a well‑defined group (a party) with a leader and members.

  • WorldManager
    Gives you game worlds / instances to run in, then cleans them up when the game ends.

  • RematchManager
    Lets players replay your game with the same teams and settings via /party rematch.

  • MashupManager
    Opt‑in support for being picked automatically in Mashup playlists.

As a game developer, you primarily:

  1. Declare your game and its capabilities (metadata).
  2. Implement methods MiniModes calls to:
    • Prepare the world
    • Spawn players
    • Handle start / end
    • Apply teams and settings
  3. Integrate with pre‑game and in‑game UIs if your game needs them.

The exact code interfaces live in the api/ package of the MiniModes plugin, but at a high level you’ll work with:

Extension metadata

Defines your extension and each game it exposes: IDs, names, descriptions, icons, player counts, flags (Mashup-compatible, supports settings, etc.).

Game implementation

One or more classes implementing the MiniModes game interface: lifecycle hooks (onPrepare, onStart, onTick, onEnd), access to players, teams, and worlds.

Settings schema

Optional schema describing your configurable options (maps, time limits, rules). MiniModes uses this to render Settings Voting and Runtime Settings GUIs.

Assets & resources

Optional assets (schematics, config files, messages, icons) accessed via the Extension Resource Manager.

Packaging (.mmx)

Your compiled code + metadata + assets, zipped/packaged into a .mmx file so the ExtensionLoader can find it and register your games.


Each game exposed by an extension needs (conceptually):

  • ID / key – stable identifier used internally
  • Name & description – what players see in the /minimodes menu
  • Min / max players – used to:
    • Validate party sizes
    • Filter games for Mashup
  • Icon – the item shown in the selection GUI
  • Tags / flags such as:
    • Mashup compatible (true/false)
    • Supports team selection (true/false)
    • Supports settings voting (true/false)
    • Supports runtime settings (true/false)

MiniModes uses this metadata to:

  • Show your game in GameSelectionGUI
  • Decide which games a party is allowed to start
  • Decide which pre‑game steps (teams, settings voting) to run
  • Know if your game can appear in Mashup playlists

To implement a game cleanly, map your logic onto MiniModes’ standard lifecycle:

  1. Registration
    When the server starts (or reloads extensions), ExtensionLoader discovers your extension and registers your game(s) with GameManager.

  2. Pre‑checks
    When a party leader picks your game from /minimodes, the engine checks:

    • Is the caller the party leader?
    • Is the party size within [minPlayers, maxPlayers]?
    • Is anyone in the party already in another game?
  3. Pre‑game flow (optional)
    Depending on your metadata, MiniModes may:

    • Open the TeamSelectionGUI to decide or shuffle teams
    • Open the SettingsVotingGUI so players vote on options (map, duration, etc.)
  4. Game preparation
    The engine:

    • Asks WorldManager to prepare a game world / instance
    • Calls your game’s prepare hook so you can:
      • Load map assets
      • Pre-place blocks or entities
      • Set gamerules / difficulty
  5. Game start
    Players are teleported in, teams and settings are passed to your game, and onStart (or equivalent) is called.
    At this point you:

    • Give players items / kits
    • Apply effects
    • Initialize your internal state and timers
  6. Game loop
    While running, your game:

    • Listens to player events (moves, damage, deaths, block interactions)
    • Updates scores, objectives, or progress
    • Optionally supports runtime settings changes via the shared GUI
  7. Game end
    You decide when the game ends:

    • Victory condition (e.g., one team left, target score reached)
    • Time limit reached
    • Manual stop by leader (/mm game stop)
    • Manual win assignment (/mm game win <players…>)

    You then:

    • Mark winners / losers
    • Clean up any custom state
    • Signal MiniModes to wrap up
  8. Cleanup & rematch
    Once the game is done, MiniModes:

    • Returns players to a lobby/spawn
    • Cleans temporary worlds
    • Stores a rematch token via RematchManager
    • Optionally triggers the next game if Mashup is enabled for the party

Your game doesn’t need to build complex inventories or titles from scratch.
Instead, you plug into shared GUIs that the core plugin already provides.

Handled entirely by MiniModes via GameSelectionGUI.
You don’t code this; you just provide good metadata and an icon.

If your game is team‑based, you can mark that in metadata so MiniModes runs TeamSelectionGUI before your game starts. It will:

  • Show all party members
  • Offer different team strategies (shuffle, manual, etc. depending on configuration)
  • Pass an already‑resolved team mapping into your game

Your game then simply consumes those teams in its logic.

For configurable games (maps, durations, rule variants), define a settings schema. MiniModes uses SettingsVotingGUI to:

  • Show options to all players at once
  • Collect votes in real time
  • Resolve a final settings object for the match

Your game receives one resolved settings object; you don’t need to handle voting yourself.

If your game supports settings that can be changed mid‑match (e.g., toggle friendly fire, adjust spawn rate):

  • Mark those as runtime‑mutable in your settings definition
  • Implement handlers that respond when a setting changes

MiniModes’ RuntimeSettingsGUI then:

  • Lets everyone view settings
  • Lets only the leader / game owner change them
  • Enforces that only runtime‑mutable options are modifiable

MiniModes guarantees that everyone is always in some party:

  • If a player is “alone”, they’re in a solo party.
  • Only the party leader can start games or Mashup.
  • Party membership is maintained across games and queues.

Your game can rely on this:

  • You always receive a coherent group of players with one leader.
  • You don’t have to manage invites, kicks, or group state.
  • Rematches and Mashup refer to the same party.

Use the party concept to:

  • Treat the party as your “lobby” or “team pool”.
  • Store small bits of state (via MiniModes APIs) keyed by the party if needed.
  • Respect leader‑only actions (e.g., only leader can open settings or start the next round, if that’s significant to your gameplay).

Mashup is MiniModes’ automatic, endless playlist.
To play nicely with it, your game should:

  • Declare itself Mashup‑compatible only if:
    • It works with a reasonable range of party sizes
    • It doesn’t assume long setup / explanation time
  • Avoid requiring complex manual configuration that Mashup can’t automate
  • Handle being started often and back‑to‑back with other games

When Mashup picks your game:

  • It ensures the party size fits your game’s min/max.
  • For settings‑capable games, it auto‑randomizes settings instead of voting.
  • It expects your game to end relatively cleanly and in a timely manner.

Mashup is great for short, replayable modes (arena duels, quick parkour, Spleef variants, etc.).


Here are recommendations to keep your extensions robust and user‑friendly:

  • Use your game instance as the single source of truth:
    • Avoid global static state unless absolutely necessary.
    • Always reset state on game end.
  • Don’t store raw Player references longer than needed; prefer UUIDs and resolve as needed.
  • Let MiniModes handle parties, selection, and basic navigation.
  • Use the provided GUIs for teams & settings instead of rolling your own unless you really need something custom.
  • Honor convention:
    • /mm game leave should cleanly detach a player from your logic.
    • /mm game spectate should be able to teleport spectators to relevant places (if supported).
    • /mm game stop should end the match and trigger your cleanup.
  • Provide sane default settings so the game is fun without configuration.
  • Make advanced options opt‑in or hidden behind settings instead of forcing them.
  • Validate settings and party size at the start of the game instance.
  • If something is misconfigured (missing map, invalid asset), fail fast and:
    • Cancel the game start
    • Let MiniModes send a clear message to the leader
  • Avoid leaving players in broken worlds or states.
  • Test a direct start via /minimodes:
    • Ensure team selection and voting behave as expected.
  • Test through Mashup:
    • Verify that randomized settings work and the game ends cleanly.
    • Make sure you don’t rely on manual steps that Mashup skips.

A typical development loop for a new extension looks like:

  1. Set up a dev server

    • Install Spigot or Paper.
    • Drop the MiniModes plugin into the plugins/ folder.
    • Enable debug logging if the plugin supports it.
  2. Create a new extension project

    • Use your preferred JVM build tool (Gradle, Maven, etc.).
    • Add MiniModes’ API as a dependency.
    • Configure your project to build a jar that MiniModes can consume.
  3. Implement your first game

    • Create an extension descriptor (metadata).
    • Implement a simple game class with minimal rules:
      • Start players in one place.
      • End after a timer or a simple event.
    • Register the game with your extension.
  4. Package as .mmx

    • Bundle your compiled classes, metadata, and assets.
    • Ensure the structure matches what MiniModes’ ExtensionLoader expects.
    • Name the file appropriately (e.g. my-first-minigame.mmx).
  5. Drop into the extensions folder

    • Put the .mmx into MiniModes’ configured extensions directory.
    • Restart/reload MiniModes to see your game appear in /minimodes.
  6. Iterate

    • Add settings and integrate with Settings Voting.
    • Add team logic and integrate with Team Selection.
    • Mark the game as Mashup‑compatible once it’s stable and quick.

Understand the game flow

Learn how party ➝ teams ➝ settings ➝ game ➝ results is orchestrated and where your code fits.

See command & API reference

Explore commands and API surfaces that your extension will interact with.

Plan your first game

Sketch a small, replayable game mode (e.g., quick duels or Spleef) and map its phases onto MiniModes’ lifecycle.

Once you’re comfortable with this conceptual model, you’re ready to dive into the concrete APIs and start building your first MiniModes extension.