For the complete documentation index, see llms.txt. This page is also available as Markdown.

🗺️Roadmap (v3)

What is coming in Modern Tournament v3 — new tournament formats, parallel matches across arenas, crash recovery and a rebuilt live bracket.

This page describes work in progress. Every step under Order of delivery has landed, apart from the items still marked as planned below; features and timing may change.

v3 is a ground-up rework of how the plugin and the online bracket talk to each other, plus the tournament formats that rework unlocks.

Why

Today the plugin and the website each build the bracket themselves. When the two copies disagree — or when a single network hiccup drops a match result — the tournament can get stuck mid-round with players left in the arena.

In v3 the website is the single authority for the bracket, and the plugin is the executor that runs the fights. There is one bracket, in one place.

What changes for you

Tournaments recover from network problems

Every result the plugin sends is queued on disk and retried until the server confirms it. If your server restarts mid-tournament, the plugin reconnects, catches up on what it missed and carries on from where it left off. A dropped request can no longer strand a tournament.

The server never freezes on /t start

All network calls move off the main thread. Starting, resetting or reconfiguring a tournament is instant regardless of how the connection to the bracket service is behaving.

New formats

Format
Status

Single elimination

✅ Proper seeding and a rendered 3rd-place match

Double elimination

✅ Winners & losers bracket, grand final with bracket reset

Round robin

✅ Everyone plays everyone; the table decides it

Groups → playoffs

✅ Snake draw into groups, then a knockout

Swiss

Planned

Best-of-N matches

✅ Configure the number of games per match, and a longer final than the rest of the tournament — Bo1 through the bracket and Bo3 or Bo5 for the last round. See Best-of-N.

Parallel matches

✅ Instead of running one duel at a time, v3 runs every ready match at once across your available arenas. A 32-team tournament goes from a long single-file queue to five quick rounds. See Parallel matches.

Crash recovery

If your server goes down mid-tournament, the plugin reconnects on restart, works out which matches were left unfinished and either replays or cancels them — instead of leaving the tournament wedged forever. You can also cancel a stuck match from the website.

Seeding you control

Randomly with a reproducible seed ✅ — the website draws the bracket from a stored seed, so the same tournament redrawn is the same tournament. Manual drag-and-drop seeding is still planned.

Spectators

/t spectate <tournament> puts you in spectator mode and follows the live match.

Reconnect grace

A player who disconnects mid-duel gets a configurable window to come back before it counts as a forfeit.

Per-tournament kits and rules

Kits, timeouts and rules can be set per tournament — and even per round — instead of only per arena.

Rewards

Run commands for each final placement, configurable in the config.

Scheduling

Give a tournament a start time, or have it start automatically once N teams have registered.

What changes on the website

  • Richer bracket — every match shows how it was won (kill, timeout, forfeit, random draw) and the winner's remaining health, plus the losers bracket, grand final and group tables for the formats that have them.

  • Live state that survives a restart — match highlighting is stored in the database rather than in memory.

  • Admin controls — override a result when something goes wrong and void a match left hanging by a server crash, both recorded in an audit log, plus a panel showing which server holds the tournament. See When a tournament goes wrong.

  • Stream overlay — a transparent view sized for OBS browser sources, showing what is being fought now. See Stream overlay.

  • Player records — tournaments entered and won, match record and win rate, counted from the matches themselves. See Player records.

  • Webhooks — tournament and match events posted to your own endpoint, signed and retried until they land. See Webhooks.

  • API tokens — named, scoped, revocable keys replacing the single permanent API key. See API tokens.

  • Creating tournaments from the dashboard — planned; they are created in-game today.

  • Drag-and-drop seeding — planned.

  • Discord integration — planned. Webhooks cover it today for anyone willing to write a relay.

  • Embeddable bracket — planned.

Compatibility

  • v3 replaces the old API rather than sitting alongside it. A 2.x plugin cannot talk to the current website, and a current plugin cannot talk to an older one — upgrade them together.

  • The plugin and the service negotiate a protocol version on connect, and tell you plainly if they are mismatched.

  • v3 requires Paper 1.20.5 or newer and a Java 21 runtime. If you are on an older server, the 2.x line continues to receive fixes — it just will not gain the v3 features on this page.

  • A tournament is run by one Minecraft server at a time. Running matches of the same tournament across several servers is not planned.

Order of delivery

  1. Stability fixes — no more main-thread freezes, no more tournaments stuck on a dropped request, live bracket state persisted.

  2. Foundations — rebuilt project structure and test coverage on both sides. The plugin now needs Java 21 and Paper 1.21.

  3. Single bracket engine — the website is authoritative, and is now the only implementation; see Bracket sync.

  4. Durable sync — offline queue, retries, crash recovery, and live push over a WebSocket. See What step 4 changed.

  5. Formats & parallel matches — double elimination, groups, best-of-N, multi-arena. See What step 5 changed.

  6. Website features — API tokens, admin controls, overlay, records, webhooks. See What step 6 changed.

What step 6 changed

Your API key is no longer one permanent key. Create a named token per server, carrying only the permissions that server needs, and revoke it on its own without touching anything else. Only a hash is stored, so a token is shown once and cannot be recovered. The account's original key still works and still carries everything; retire it by moving your servers onto tokens and then refreshing it. See API tokens.

A tournament that goes wrong can be fixed. Set a winner by hand, or void a match a crashed server left hanging, both from the dashboard with a reason that is recorded. Changing a match replays the bracket, so everything that followed from it is recomputed and you are told what could no longer have happened. The same panel names the server holding the tournament, which is the answer to "why will it not start". See When a tournament goes wrong.

Every tournament has a stream overlay. A transparent browser source showing the matches being fought and the champion when there is one, on the same live connection as the bracket page. See Stream overlay.

Player records across your tournaments, counted from the matches every time rather than kept as totals — so a corrected result is reflected at once and nothing can drift.

Webhooks. Tournament and match events posted to your own endpoint, signed so you can verify them and retried for a day before being given up on. See Webhooks.

What step 5 changed

There are four formats instead of one. Double elimination, round robin and groups → playoffs join single elimination, and settings.format.type picks between them. The plugin tells the website which one it means when the tournament starts, so both ends draw the same tournament rather than each assuming.

Under the hood this is one change, not four. A tournament used to advance a winner by arithmetic — the next round, at half the position — which is correct for exactly one shape of bracket. Now the draw states, for every match, where its winner goes and where its loser goes, and one tested engine follows those instructions whatever the format. A losers bracket is not a special case; it is the same engine reading a different set of arrows.

A match can be more than one game. best_of and best_of_final set how many, and the same two teams play until one has a majority. Each game is reported as it finishes, so the online bracket shows the score as it stands. A game nobody turns up for settles the whole match rather than dragging a decided result through two more countdowns.

Matches are addressed by bracket as well as by round. Winners round 2 and losers round 2 are different matches between different teams, so a round and a position no longer name one on their own. If you drive the API yourself, the result and state endpoints moved from /matches/{round}/{order} to /matches/{bracket}/{round}/{order}.

Your arenas are all used. max_parallel_matches caps how many matches run at once, each in its own arena. It defaults to 1, which is exactly the old behaviour, so nothing changes until you raise it.

The bracket page shows the whole tournament. The losers bracket, the grand final and group tables are rendered alongside the main tree instead of being left out of it.

What step 4 changed

A result can no longer be lost. The plugin writes each one to disk before it tries to send it, and keeps retrying until the website confirms it — through an outage, through a restart, for as long as it takes. Sending the same result twice is safe, so a retry after a timeout cannot duplicate or contradict anything. Previously a failed send was logged and dropped, and the online bracket quietly fell behind.

A crashed server no longer wedges a tournament. A tournament is executed by one server, which claims it on start. If that server dies, the match it was running is left unfinished; when it comes back it claims the tournament again, that match is reopened and played, and the server tells you in the log which ones those were. A server that has been superseded — because another one took over, or because it restarted — is refused if it tries to report an old result, so a bracket can never become a mixture of two runs.

If a tournament is held by a server that is gone for good, it can be taken over deliberately from the other machine.

A spectator who loses connection catches up. The bracket page holds a WebSocket to the site, and a reconnect is sent exactly what it missed, in order, instead of silently sitting on a stale bracket until someone reloads.

What step 3 changed

The website now draws the bracket once, when a tournament starts, and stores it — every match of every round, with byes already awarded. It used to rebuild the bracket from the current team list every time anyone asked for it, which meant a tournament's shape could change under it while it was being played.

Recording a result and moving the winner into the next round now happen together, so the bracket is never seen with a decided match whose winner has not appeared yet. A result the bracket cannot justify — a winner who was not in the match, a second different winner for a match already decided — is refused rather than stored.

Each tournament also keeps a numbered log of everything that has happened to it, which is what step 4 builds on: a plugin or a browser that was disconnected can ask for what it missed instead of refetching and hoping.

Last updated