Extension
Your game logic and assets, packaged into an mmx file
Your game logic and assets, packaged into an mmx file
Everything you need to interact with Minecraft using MiniModes
MiniModes automatically translates your game to run on ANY platform, like a Paper server or a Fabric mod
An extension is a loadable game pack. The engine scans extension artifacts for @Game classes, creates game instances, binds a GameRuntime, and registers declared resources.
Extension artifacts conventionally build with Shadow and use the .mmx extension:
plugins { kotlin("jvm") id("com.gradleup.shadow")}
dependencies { compileOnly(project(":miniModes-api")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")}
tasks.shadowJar { archiveClassifier.set("") archiveBaseName.set(project.name) archiveVersion.set(project.version.toString()) archiveExtension.set("mmx")}The important dependency choice is compileOnly(project(":miniModes-api")). The server supplies MiniModes. The extension compiles against the API and packages only its own helper code and required libraries.
The API layer gives you stable, platform-neutral handles:
GameTemplate and SettingsGameTemplate for lifecycle and game state.GamePlayer, GameWorld, GameInventory, GameEntity, and GameVehicle for server objects.EventsScope for normalized game events.GameCommandsScope and GameInputTypes for typed local commands and prompts.ItemDSL, sidebar, doubleJump, entity, projectile, vehicle, areas, and route.The API does not force a single game structure. A tiny Spleef game can stay in one class; a larger mode can split arena generation, settings config, weapons, and scoring into separate files.
Core services own shared behavior:
The Platform interface is the port surface implemented by server adapters:
interface Platform { val scheduler: PlatformScheduler val worlds: PlatformWorlds val players: PlatformPlayers val events: PlatformEvents val entities: PlatformEntities val projectiles: PlatformProjectiles val vehicles: PlatformVehicles val doubleJump: DoubleJumpService}Paper and Fabric adapters translate those calls into native server behavior. Extension code should stay above this layer unless it is intentionally doing adapter-specific work.
Every match has a gameId. The runtime uses it to scope:
When a game ends through endGame, endGame(outcome), or manager cancellation, GameRuntime.dispose() unsubscribes events, cancels tasks, cleans platform registries for entities/projectiles/vehicles, clears player handles, and runs finalization hooks. World cleanup is performed by the game shutdown path.
That scoping is the core ergonomic promise of MiniModes: a game can create runtime objects liberally without hand-rolling cleanup lists for every feature.