You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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_players and weight fields. Backward compatible with plain strings.
Per-lobby max-player cap — servers at their max_players capacity 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 status commands 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 global selection_mode.
Fallback Priority Chain — ordered fallback groups when a contextual group's servers are all unavailable.
Player Affinity Routing — sticky sessions with configurable stickiness probability (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 NavigatorAPI methods: getRoutingDistribution(), getHealthCheckLatencies(), getCircuitBreakerStatuses().
Connection Rate Tracking — sliding window (60-second) connection rate tracker used by least_connections mode.
Server Load Tracking — EMA-based server load tracker used by least_connections mode.
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.
Admin join update notification — players with velocitynavigator.admin permission are notified in-game when they join if an update is available. Controlled by notify_admins_on_join config.
<player> placeholder — new placeholder available in all message templates.
<attempt> and <max> placeholders — available in messages.retrying.
messages.retrying config — new message template for connection retry notifications.
notify_admins_on_join config — 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_VERSION set to 4. Auto-migration from v3 configs with .bak backup.
Changed
Removed .join() blocking call in onPlayerChooseInitialServer — 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>> to Map<String, GroupConfig> where GroupConfig contains servers and optional mode.
UpdateChecker — removed recurring schedule; now runs a single check on startup. Removed enabled, notifyConsole, startupDelaySeconds fields.
ConfigManager — reads both plain strings and inline tables for lobby entries (backward compatible). Writes inline tables when max_players or weight is non-default.
MessageFormatter — added player, attempt, max to allowed placeholders.
noLobbyFound message — now includes (<reason>) placeholder by default.
ServerCandidate record — now includes effectiveWeight and emaLoad fields.
RouteDecision — provides ordered candidate list for retry fallback.
Fixed
Blocking .join() in event handler — onPlayerChooseInitialServer no 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.bypasscooldown now also checks velocitynavigator.bypass.cooldown for consistency.
Deprecated
velocitynavigator.bypasscooldown permission — use velocitynavigator.bypass.cooldown instead. The legacy name still works as a fallback.
Removed
update_checker.enabled config field — the update checker now always runs on startup.
update_checker.notifyConsole config field — update notifications are always logged to console.
update_checker.startupDelaySeconds config field — startup delay is fixed at 5 seconds.
Recurring update check schedule — replaced by one-time startup check and /vn updatecheck.