A high-fidelity MIDI player for Minecraft, built around native note blocks and an optional enhanced-audio resource pack.
Created by Ryder.
MidiBox turns Standard MIDI files into a shared Minecraft listening experience. It reads MIDI timing, tempo changes, instruments, percussion, velocity, pitch bend, sustain, and channel controls; translates them into a native note-block arrangement; and gives players an iPod-inspired in-game music player.
The current plugin includes:
- MIDI discovery, compilation, and an atomically written playback cache.
- Tempo-correct, per-player playback with lag-resistant scheduling.
- Native General MIDI instrument mapping, percussion routing, octave fitting, and range diagnostics.
- An in-game Home, Music Library, Now Playing, and Settings player flow.
- Persistent volume, history, playlists, queues, and audience playback.
- An optional resource-pack bridge for richer custom instrument samples.
- Uses MIDI tempo maps and an absolute monotonic playback clock instead of a simple tick counter.
- Uses Java's strict Standard MIDI reader first, then a conservative recovery reader for malformed real-world exports; recovery keeps valid events and reports discarded malformed ones rather than inventing musical data.
- Uses a configurable pre-roll, one-tick outbound look-ahead, and bounded per-player ping compensation, so sound packets leave the server before their intended beat without changing the shared song clock.
- Supports program changes, channel volume, expression, pitch bend, percussion, and sustain-pedal approximation.
- Batches simultaneous chords in musical-priority order and adaptively sheds soft accompaniment/sustain refreshes before drums, bass attacks, or strong melody notes when a server tick is late.
- Runs
/music analyze <song>to report octave shifts and notes that needed native range clamping.
/musicopens a Home screen with Music, Now Playing, and Settings.- The Library supports paged song browsing; click to play and shift-click to queue.
- Now Playing shows live elapsed time, a progress bar, playback state, and voice-protection feedback.
- Player volume is saved independently for every UUID.
- Songs are read from
plugins/MidiBox/songs/, including nested folders. - Player profiles persist recently played tracks and named playlists in
plugins/MidiBox/players.yml. - Share music with yourself, a selected player, everyone in a radius, or the whole server through permission-gated commands.
- Place a bold red JUKEBOX to create a persistent public player; right-click it to open the Music Library. It owns one shared song timeline: listeners entering its configured radius join at the current position, and listeners leaving the radius stop hearing it. The footer provides an operator-only public/operator access toggle and a shared repeat toggle; shift-click a song to queue it for everyone nearby.
- Vanilla listeners always receive a complete native note-block arrangement.
- Players who accept the configured enhanced-audio pack receive custom
midibox:instrument and percussion sounds instead. - The resource-pack template defines the sample layout without bundling unlicensed audio assets.
- The default balanced orchestra uses curated, locally available vanilla sound events to extend melodic coverage beyond the note-block palette.
- Bundled orchestra profiles use explicit versions: MidiBox replaces an installed profile only when a newer bundled profile version ships, while same-version server tuning remains untouched.
- Each MIDI part selects one coherent source by instrument role and safe pitch fit, rather than switching sounds for every note.
- Administrators can use
/music orchestra listand/music orchestra audition <id> [midi-note]to tune the palette by ear.
/music Open the player
/music play <song> Play for yourself
/music play <song> @Player Play for one player (permission required)
/music play <song> radius 50 Play nearby (permission required)
/music play <song> global Play for everyone (permission required)
/music pause | resume | stop
/music volume <0-100>
/music jukebox Receive a permanent public JUKEBOX (operator only)
/music history
/music playlist list|create|add|play|delete
/music analyze <song>
/music pack Request optional enhanced-audio pack
/music reload Rescan the library (admin)
- Paper for Minecraft
1.21through1.21.11, or26.1through26.2 - Java
21for Minecraft 1.21.x; Java25for Minecraft 26.x
- Build the plugin with
gradle build. - Copy
build/libs/midibox-0.1.0.jarinto the Paper server'splugins/directory. - Start Paper once so it creates
plugins/MidiBox/. - Add
.midor.midifiles underplugins/MidiBox/songs/. - Run
/music reload, then/musicin game.
MidiBox stores runtime data inside the Paper plugins directory under MidiBox/.
MidiBox/config.yml: playback, UI, limits, and enhanced-audio settingsMidiBox/songs/: source MIDI library and optional.song.ymlsidecarsMidiBox/cache/: generatedMBC3playback cache; safe to delete and rebuildMidiBox/players.yml: per-player volume, history, and playlists
Place a sidecar next to a song, such as songs/ambient/sweden.song.yml. transpose shifts every melodic part; channels are zero-based MIDI channels (9 is percussion).
transpose: 0
channels:
"0":
transpose: -12
sound: GUITARValid sound values include HARP, BASS, BELL, FLUTE, GUITAR, CHIME, XYLOPHONE, IRON_XYLOPHONE, COW_BELL, DIDGERIDOO, BIT, BANJO, and PLING.
Use resource-pack-template/README.md as the starting point for a separately hosted resource-pack ZIP.
- Add appropriately licensed
.oggsamples to the template's instrument and percussion paths. - Zip the contents of the template folder and host the ZIP over HTTPS.
- Calculate the ZIP's SHA-1.
- Set
enhanced-audio.enabled,resource-pack.url, andresource-pack.sha1inMidiBox/config.yml.
Players who decline an optional pack automatically remain on native note-block audio.
plugin.ymldeclaresapi-version: '1.21'.- Runtime code uses stable Bukkit/Paper APIs and avoids NMS or CraftBukkit internals.
- The Java 21 plugin JAR works on supported 1.21.x servers and on Paper 26.x running its required Java 25 runtime.
- The enhanced resource pack is optional; native audio remains the compatibility baseline.
gradle clean buildThe release JAR is written to build/libs/midibox-0.1.0.jar.
gradle test
gradle clean build
gradle verifyReleaseArtifactThe test suite covers MIDI tempo conversion, note releases, program changes, controller events, cache round-trips, malformed source rejection, and recovery of valid notes around malformed events. verifyReleaseArtifact also checks the final JAR contains required metadata/resources, does not bundle Paper API classes, and targets Java 21 bytecode.
| Component | Version |
|---|---|
| Plugin Version | 0.1.0 |
| Supported Minecraft Versions | 1.21 - 1.21.11, 26.1 - 26.2 |
| Paper API Baseline | 1.21 |
| Java | 21 for 1.21.x; 25 runtime for 26.x |
| Cache Format | MBC3 |
- MIDI compilation uses a worker thread; Bukkit sound calls stay on the server thread.
- Source MIDI files are capped at 32 MiB and cache writes are atomic.
playback.max-events-per-tickbounds work after lag spikes;max-voices-per-playerprotects listeners from dense chords.playback.timingcontains the server-side latency controls. The default 200 ms pre-roll and ping compensation are intentionally conservative; tune only after listening on the real server.- The permanent JUKEBOX creation button and
/music jukeboxare visible/available only to server operators. Placed jukeboxes remain public listeners for their configured radius. - Native note blocks cannot provide continuous pitch bends or true sustained samples. MidiBox applies bend/volume to upcoming notes and gently layers long held notes plus sustain-pedal tails as the closest native approximation.
For now, use the project repository's issue tracker for bugs, MIDI files that map poorly, and feature requests.
MidiBox is distributed under the custom MidiBox License (All Rights Reserved) in LICENSE.txt.