Tags
Creators
Details
All versions
4.0.0
Release
VelocityNavigator 4.0.05 months ago 35
Uploaded by
Compatibility
Minecraft: Java Edition
26.1.x
1.21.x
1.20.x
Platform
Velocity
Changes
[4.0.0] — 2026-05-01
Added
- Power of Two selection algorithm (
power_of_two) — picks two random candidates, selects the one with fewer players. Near-optimal distribution at O(1) cost. - Weighted Round Robin selection algorithm (
weighted_round_robin) — interleaved WRR that distributes traffic proportionally to server weights. - Least Connections selection algorithm (
least_connections) — selects the server with the lowest exponential moving average (EMA) of connection load and rate. - Consistent Hash selection algorithm (
consistent_hash) — deterministic player-to-server mapping using a consistent hash ring with 150 virtual nodes and SHA-256 hashing. Provides session affinity. - LobbyEntry format — servers can be configured as plain strings or inline tables with
max_playersandweightfields. Backward compatible with plain strings. - Per-lobby max-player cap — servers at their
max_playerscapacity are automatically excluded from routing. - Circuit Breaker — automatic server failure detection with CLOSED → OPEN → HALF_OPEN state machine. Unhealthy servers are excluded from routing until they recover.
- Server Drain Mode —
/vn drain <server>,/vn undrain <server>,/vn drain statuscommands for graceful server maintenance. - Connection Retry with Fallback — automatic retry on connection failure with configurable
max_retries. Shows retry message with<attempt>/<max>placeholders. - Per-Group Selection Mode Override — contextual routing groups can specify their own
mode, overriding the globalselection_mode. - Fallback Priority Chain — ordered fallback groups when a contextual group's servers are all unavailable.
- Player Affinity Routing — sticky sessions with configurable
stickinessprobability (0.0–1.0). Players tend to return to their previous lobby. - Graceful Degradation — when all health checks fail, fall back to a configured degradation mode (default:
random) instead of showing "No lobby found". - Geo-Based Routing (experimental) — stub implementation for geo-based lobby routing using MaxMind GeoLite2 Country database.
- Routing Metrics API — new
NavigatorAPImethods:getRoutingDistribution(),getHealthCheckLatencies(),getCircuitBreakerStatuses(). - Connection Rate Tracking — sliding window (60-second) connection rate tracker used by
least_connectionsmode. - Server Load Tracking — EMA-based server load tracker used by
least_connectionsmode. - Routing Stats — per-server connection counts with 60-second reset, shown in
/vn status. - Enhanced /vn status dashboard — now shows circuit breaker status, drained servers, and routing distribution.
/vn updatecheckcommand — manually check for updates (replaces recurring auto-update check).- Startup update notification — one-time update check 5 seconds after proxy start.
- Admin join update notification — players with
velocitynavigator.adminpermission are notified in-game when they join if an update is available. Controlled bynotify_admins_on_joinconfig. <player>placeholder — new placeholder available in all message templates.<attempt>and<max>placeholders — available inmessages.retrying.messages.retryingconfig — new message template for connection retry notifications.notify_on_startupconfig — suppress startup update notification.notify_admins_on_joinconfig — enable/disable in-game admin update notification on join.- Health check cache purge — expired cache entries are automatically purged every 60 seconds.
getCachedOnlineServers()method — synchronous cached player count access for initial join balancing (replaces blocking.join()call).- Config version field —
CURRENT_VERSIONset to 4. Auto-migration from v3 configs with.bakbackup.
Changed
- Removed
.join()blocking call inonPlayerChooseInitialServer— replaced with synchronous cache lookup. Falls through to Velocity's built-in try list on cold start. - Round-robin state only resets when lobby topology changes —
applyLoadedConfiguration()now compares previous and current lobby lists before resetting. - Contextual groups — changed from
Map<String, List<LobbyEntry>>toMap<String, GroupConfig>where GroupConfig containsserversand optionalmode. - UpdateChecker — removed recurring schedule; now runs a single check on startup. Removed
enabled,notifyConsole,startupDelaySecondsfields. - ConfigManager — reads both plain strings and inline tables for lobby entries (backward compatible). Writes inline tables when
max_playersorweightis non-default. - MessageFormatter — added
player,attempt,maxto allowed placeholders. noLobbyFoundmessage — now includes(<reason>)placeholder by default.ServerCandidaterecord — now includeseffectiveWeightandemaLoadfields.RouteDecision— provides ordered candidate list for retry fallback.
Fixed
- Blocking
.join()in event handler —onPlayerChooseInitialServerno longer blocks the event loop with.join()calls. Uses cached data synchronously instead. - Round-robin reset on every reload — round-robin counter is now only reset when the lobby topology actually changes, preventing unnecessary redistribution on config reload.
- Health check cache memory leak — expired cache entries are now purged every 60 seconds.
- Permission node inconsistency —
velocitynavigator.bypasscooldownnow also checksvelocitynavigator.bypass.cooldownfor consistency.
Deprecated
velocitynavigator.bypasscooldownpermission — usevelocitynavigator.bypass.cooldowninstead. The legacy name still works as a fallback.
Removed
update_checker.enabledconfig field — the update checker now always runs on startup.update_checker.notifyConsoleconfig field — update notifications are always logged to console.update_checker.startupDelaySecondsconfig field — startup delay is fixed at 5 seconds.- Recurring update check schedule — replaced by one-time startup check and
/vn updatecheck.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:2rbkszFo:BWNPItX4"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:2rbkszFo:BWNPItX4"
}

