⚡ VelocityLimboHandler
🌀 A smart limbo & queue handler for Velocity
Keeps your players connected, calm, and coming back even when backend servers crash.
✨ Why VelocityLimboHandler?
- 🚦 Per-Server Smart Queue – players only wait for the server they were on, not behind others stuck elsewhere
- 📢 Queue Updates – automatic position notifications keep players informed
- 🔒 Protected Limbo – blocks unwanted commands to prevent bypasses
- 🛠️ Maintenance Support – respects whitelist & bypass permissions
- 🤝 Authentication Ready – seamless integration with authentication plugins such as LibreLogin or nLogin
👉 Full setup & advanced features in the Wiki.
Made to work with LOOHP's Limbo server, but any other server is also fine.
🧩 Compatibility
- 🖥️ Proxy: Velocity (all recent versions)
- 🎮 MC Versions: All versions
- 📜 License: MIT
🚀 Quick Install
- Grab the latest
.jarfrom Releases. - Drop it into your Velocity
pluginsfolder. - Restart the proxy (config files will generate).
- Adjust
config.yml+messages.ymlto your liking. - Restart once more — done! 🎉
⚙️ Config Highlights
# config.yml
limbo-name: "limbo" # The name of your limbo server
direct-connect-server: "lobby" # Where to send direct connections
task-interval: 3000 # Queue processing interval (milliseconds)
reconnect-batch-size: 8 # Maximum backend queues checked per processing run
queue-notify-interval: 30 # How often to tell players their position
queue-notify-batch-size: 64 # Maximum due notifications sent per dispatcher tick
disabled-commands: ["server","hub"] # Commands blocked in limbo
The batch limits smooth work across scheduler ticks. Increase them for faster catch-up on very large networks, or lower them to cap short CPU bursts on constrained proxies.
👉 Messages can be tweaked in messages.yml so your players see exactly what you want.
🖧 Proxy Setup Example
[servers]
lobby = "127.0.0.1:25566"
limbo = "127.0.0.1:25569"
# Keep normal logins on Lobby. VLH intercepts a loss of the current backend itself.
try = ["lobby", "limbo"]
[advanced]
# Required for VLH to recover players after an ungraceful backend disconnect.
failover-on-unexpected-server-disconnect = true
[forced-hosts]
"pvp.example.com" = ["pvp", "limbo"]
"build.example.com" = ["build", "limbo"]
🛡️ Permissions & Integrations
- Players get queued automatically, no setup required.
- Commands blocked per config.
- LibreLogin support ensures login/auth flow isn’t broken.
- Maintenance plugins are respected (bypass logic included).
🤝 Contributing
Pull requests are welcome! Just follow the style already in place.
Check CONTRIBUTING.md for details.
📖 License
Licensed under MIT, free to use, modify, and distribute, including in closed-source projects. See LICENSE for details.
All Versions
+ Add Version| Name | Game version | Platforms | Published | Downloads | Actions |
|---|---|---|---|---|---|
| 8h ago | 1 | ||||
|
R
v1.8.3
|
8h ago | 1 | |||
| 8h ago | 1 | ||||
| 8h ago | 1 | ||||
|
R
v1.8.1
|
8h ago | 1 | |||
| 8h ago | 1 | ||||
| 8h ago | 1 | ||||
| 8h ago | 1 | ||||
|
R
v1.7.0
|
8h ago | 1 | |||
|
R
v1.6.2
|
8h ago | 1 | |||
|
R
v1.6.1
|
8h ago | 1 | |||
| 8h ago | 1 | ||||
|
R
v1.5.0
|
8h ago | 1 | |||
|
R
v1.4.0
|
8h ago | 1 | |||
| 8h ago | 1 | ||||
|
R
v1.2.0
|
8h ago | 1 | |||
|
R
v1.1.1
|
8h ago | 1 | |||
|
R
v1.1.0
|
8h ago | 1 | |||
|
R
v1.0.1
|
8h ago | 1 | |||
| 8h ago | 1 |
### New features
- Developer API v1**: Velocity plugins can move players into limbo, pause players or whole servers with holds, change a player's destination, read queue state, and react to limbo events. See the [Developer API v1 guide](https://github.com/AkselGlyholt/velocity-limbo-handler/wiki/Developer-API-v1).
- Holds in
/vlh status**: The status command now shows how many players and servers are currently held. - Version checker**: On startup, VLH checks for a newer release in the background and logs a download link if one is available. Startup continues normally if the check fails.
- Debug option**: Set
debug: trueto log virtual-host resolution, queue assignment, and ping results when troubleshooting a setup or plugin conflict.
### Improvements
- Performance on large networks**: Queue lookups are indexed and queue positions are cached. Only queues with players waiting are processed. Backend pings are coalesced, cached briefly, and back off for servers that are offline.
- Tuning options**:
reconnect-batch-size(default8) andqueue-notify-batch-size(default64) spread reconnect and notification work across ticks, so large networks can balance catch-up speed against scheduler load. - Safer reloads and startup**:
/vlh reloadapplies the new configuration all at once and rejects invalid server names instead of half-applying them. VLH stops at startup if the configuration can't be loaded.
### Fixes
- Players are recovered correctly after their backend disconnects.
- Maintenance status is rechecked after backend pings.
- Disconnect reason matching no longer depends on the server's locale.
- Scheduled work is cancelled cleanly on proxy shutdown.
### Upgrading
- Replace the plugin JAR. Your existing
config.ymlis updated automatically with the new options, and no other changes are needed. - Java 21 is still required.
- VLH is now licensed under **MIT** (previously GPL-3.0).
### For developers
Add the API as a
compileOnly/provided dependency from JitPack, and declare velocity-limbo-handler as a required Velocity dependency. Don't shade it.compileOnly("com.github.AkselGlyholt.velocity-limbo-handler:velocity-limbo-handler-api:v2.0.0")
The internal
getPlayerManager() and getReconnectBlocker() accessors are deprecated. Use VelocityLimboApi.get(proxy) instead.## What's Changed
- Debug option by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/78
- Optimize queue processing and runtime resource usage by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/81
- Version checker by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/83
- feat(api): add stable developer API v1 by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/82
### New features
- Command blocking message configuration** — The message shown when commands are blocked in limbo can now be customized via config. Also includes an updated event listener for command blocking.
- Extended placeholders** — Additional placeholders are now available for use in messages/config.
- Toggleable connection warnings** — Connection warning messages can now be enabled or disabled in config.
### Improvements
- Disconnect reason handling** — Refactored to use component inspection instead of string matching, making reason detection more robust and reliable across different server implementations.
/vlh reloadand/vlh statusadmin commands.reloadhot-reloads the plugin configuration without a server restart;statusprovides a runtime overview of the handler's current state.
### Changed
- Refactored internal queue state management for improved reliability and clarity.
- Introduced tiered priority to the reconnect queue, allowing higher-priority players or conditions to be processed ahead of the standard queue. This replaces the previous flat queue model.
This is a development snapshot. Expect instability. Do not deploy blindly into production.
Is more or less stable, but don't trust it 100%
## Added
###
/vlh Admin Commands- Implemented
/vlh reload - Implemented
/vlh status
These commands allow:
- Reloading configuration without full proxy restart
- Inspecting current limbo handler state
## FastStats Integration
- Integrated FastStats metrics support [faststats.dev](https://www.faststats.dev)
- Full Changelog:**
### What's Changed
- State Management: Refactored PlayerManager to use UUID-based structures. This fixes stale Player object references and improves memory safety across reconnects.
- Logic Fixes:
- Fixed a bug in QueueNotifierTask where a single maintenance-queued player would abort the entire task.
- Corrected ReconnectionTask maintenance bypass logic to properly handle permissions and whitelists.
- Prevented player "starvation" by ensuring failed reconnection attempts no longer block the rest of the group.
- Optimizations: Added cached reflective lookups in Utility for maintenance API checks, reducing overhead during heavy reconnect loops.
### 📊 Performance Improvements (May vary depending on setup)
- CPU Optimization: Reduced core processing overhead by approximately 35% thanks to more efficient queue handling and cached reflection.
- Memory Efficiency: Drastically improved heap management. By migrating to UUIDs and pruning stale references, the memory footprint is reduced by ~50% under load compared to v1.8.0.
Full Changelog: https://github.com/AkselGlyholt/velocity-limbo-handler/compare/v1.8.0...v1.8.1
This release focuses on authentication improvements, internal structure, and developer experience. It also lays groundwork for safer iteration going forward.
### What’s Changed
- Deprecated
auth-timeout**
auth-timeout option is now deprecated. It remains available for compatibility but should be considered end-of-life. Plan migrations accordingly.PR: #48
- Added NLogin authentication support**
PR: #54
Contributor: @ArturoAtomplay
- Improved developer experience with JSDoc**
PR: #57
- Added unit tests for core components**
PR: #59
- Refactor: modularized codebase and extracted core logic**
PR: #58
### New Contributors
- @ArturoAtomplay made their first contribution with the NLogin authentication implementation.
### Full Changelog
[https://github.com/AkselGlyholt/velocity-limbo-handler/compare/v1.7.0...v1.8.0](https://github.com/AkselGlyholt/velocity-limbo-handler/compare/v1.7.0...v1.8.0)
## What's Changed
- deprecated auth-timeout by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/48
- Add NLogin authentication support by @ArturoAtomplay in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/54
- Fix formatting issues in build.yml by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/56
- Added JSDoc to improve dev experience by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/57
- Add Unit Tests for Core Components by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/59
- Refactor: Modularize codebase and extract core logic by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/58
## New Contributors
- @ArturoAtomplay made their first contribution in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/54
## What's Changed
- deprecated auth-timeout in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/48
- Added nLogin authentication support by in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/54
## New Contributors
- @ArturoAtomplay made their first contribution in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/54
## ⚠️ Important: Configuration Migration
If you are updating from **v1.6.2** or lower, your
task-interval unit has changed.- Old behavior:** Seconds (e.g.,
3) - New behavior:** Milliseconds (e.g.,
3000) - Action Required:** Please update your
config.ymlto reflect this change, otherwise, the plugin will attempt to reconnect players far too fast!
## 🛠️ Performance & Stability
This update brings major internal improvements to ensure the proxy remains responsive even under heavy load.
- Non-Blocking Reconnections:** All server pings and connection requests are now handled **asynchronously**. This prevents "Proxy Hangs" if a backend server is slow or timing out.
- Full Server Protection:** Added a "Pre-flight" check. The plugin now pings the target server and checks player capacity **before** attempting a connection. This eliminates the "Server is full" console spam and reduces network overhead.
- Memory Management:** Fixed several memory leaks where disconnected players were remaining in internal tracking maps.
## ✨ New Features & Fixes
- New Integration:** Added support for **LibreLoginNext** in the AuthManager.
- Queue Logic:** Fixed a bug where players could sometimes "skip" the queue under specific timing conditions.
- Smart Rerouting:** Improved the connection listener to detect "Intentional" reconnections, preventing players from getting stuck in a loop between Limbo and the Lobby.
## 📦 Pull Requests
- Added LibreLoginNext support (#41)
- Unit migration: task-interval to milliseconds (#42)
- Core: Async implementation and leak fixes (#43)
- Fix: Logic to handle full backend servers (#44)
- Bugfix: Resolved queue skipping issues (#45)
### What’s New
- Bugfix:** Improved CloudNet support.
### Links
- Full changelog:** [v1.6.1 → v1.6.2](https://github.com/AkselGlyholt/velocity-limbo-handler/compare/v1.6.1...v1.6.2)
- Bug Fixes**
- Fixed an issue where players could still be kicked for auth timeout even after authenticating with LibreLogin. This happened due to event ordering between Velocity and LibreLogin. Blocking now happens earlier in the login pipeline, ensuring proper unblock order.
- Improvements**
- Logs are clearer: integration with LibreLogin is only logged if the plugin is truly active.
- Notes**
- This release should resolve the “authenticated but still kicked” bug some servers experienced with LibreLogin.
This update adds **native support for LibreLogin authentication** and smarter queue handling for players who haven’t logged in yet.
### ✨ New Features
#### **LibreLogin Auto-Detection**
- Automatically detects the
libreloginplugin at runtime — **no configuration needed**. - Uses reflection to hook into
getLibreLogin().getEventProvider()and listen for theauthenticatedevent. - Instantly unblocks players from Limbo as soon as they authenticate.
#### **Auth-Aware Queue System**
- Players awaiting authentication are **not placed** into the reconnect queue.
- On successful authentication, players are seamlessly restored to their correct per-server queue position.
- Configurable timeout for authentication waiting (
-1to disable).
### ⚡ Improvements
- Queue processing now **skips blocked players**, so pending logins never delay others.
- Player re-queuing after authentication happens automatically — no manual action required.
### 🐛 Bug Fixes
- Fixed rare edge cases where reconnects during authentication could misplace players in the queue.
### 📝 Notes
- If LibreLogin is not installed, the plugin behaves exactly as before.
- Tested on **Velocity 3.4.0-SNAPSHOT** with the latest LibreLogin build.
- Bypass Maintenance Mode:** Players with permission can now skip the queue even when maintenance mode is active.
- Per-Server Queues:** Added support for separate queues per target server.
### Improvements
- Maintenance Whitelist Respect:** Players on the Maintenance plugin’s whitelist are no longer blocked by the queue.
- Logging:** The logger now uses the Plugin name, instead of the Class
### Cleanup & Fixes
- Fixed a bug where players weren't properly removed from the queue.
- General code cleanup and refactoring for better maintainability.
You can now customize message inside the
messages.yml file. Looking inside the file should be pretty self-explanatory, but further documentation will be added in the future. (On GitHub)- Feature/message config by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/13
- Added bStats
Will now handle when the Backend server is in maintenance mode, and prevent chat/console spam by not attempting to send players through, until maintenance is back off again
- Feature/maintenance integration by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/11
- Fixed connection error bug, when no forced-hosts are set
- Added command blocker by @AkselGlyholt in https://github.com/AkselGlyholt/velocity-limbo-handler/pull/9
New config section to edit disabled commands in limbo server
``
yml
# A list of disabled commands, which will not work inside the Limbo server. Recommended commands are ones that the player can use to transfer server, like /server or /hub
disabled-commands: ["server", "lobby", "hub"]
``- Fix queue message for disabled mode by @AkselGlyholt in [#7](https://github.com/AkselGlyholt/velocity-limbo-handler/pull/7)
- Fixed player reconnected to direct-connect server, and not intended server when using forced-hosts by @AkselGlyholt in [#8](https://github.com/AkselGlyholt/velocity-limbo-handler/pull/8)
## Overview
This update enhances the player experience by significantly improving how connection errors are handled. Players who are banned or not whitelisted on destination servers now remain in limbo with appropriate notifications rather than being disconnected.
## New Features
- Players now receive clear, color-coded notifications when they cannot connect to a server due to bans or whitelist restrictions
- Added persistent tracking of player connection issues (banned/not whitelisted)
- Improved queue system to properly skip players with connection issues
## Bug Fixes
- Fixed issue where banned players were kicked from the proxy entirely
- Fixed queue system becoming blocked when a player with connection issues was at the front of the queue
- Fixed error message detection to properly identify ban and whitelist messages
## Technical Improvements
- Enhanced error detection by checking both exception messages and server response components
- Improved connection failure handling with proper categorization of error types
- Made connection issue notifications independent of queue status
## Configuration
- Added "queue-enabled" to toggle if the queue should be enabled, or just use random selection from players (Only recommended for small servers to keep it fair)
- This release focuses on creating a more stable experience for players during server maintenance and restarts while preventing unnecessary disconnections.*
Fixed servers config not loading custom server names properly.
## Features
- Automatic reconnecting to previous server before crash
- Automatic reconnecting to main server if full/down
- Queue system for reconnecting players