## ✨ Major Features
### New Plugin API Module
- **Public API for third-party plugins** — New `ezrtp-api` artifact that allows other plugins to trigger random teleports programmatically
- Simple helper methods in `EzRtpAPI` for common use cases, with optional callbacks for async operations
- Bukkit Services Manager integration for clean dependency injection
- Minimal compile-time footprint — only `ezrtp-api` needs to be in the classpath of dependent plugins
### Performance Monitoring & Observability
- **Performance metrics collection** — Track RTP operation timings, cache efficiency, chunk loads, and biome filter performance
- **Slow RTP warnings** — Automatically detect and log RTPs that exceed a configurable threshold (default 100ms)
- **Percentile tracking** — Snapshot P50, P75, P90, P95, P99 response times using a ring-buffer sample
- **Periodic JSON export** — Export metrics to JSON for integration with monitoring systems or manual analysis
- New `/rtp stats performance` subcommand to view current metrics in-game
- **Configurable via** `plugins/EzRTP/performance.yml`
### Unsafe Location Monitoring
- **Track rejection causes** — Understand why locations are unsafe (void, liquid, lava, unsafe blocks, etc.)
- **Per-cause statistics** — Breakdown of all-time rejection counts by cause
- **Optional warning system** — Log or warn when unsafe rejection rate exceeds a threshold
- **Periodic metrics export** — Export rejection statistics to JSON
- New `/rtp unsafe-stats` subcommand to view unsafe location statistics in-game
- **Configurable via** `plugins/EzRTP/unsafe-location-monitoring.yml`
### Improved Chunk Loading
- **Paper 1.21+ async API detection** — Automatically use `World.getChunkAtAsync()` on qualifying servers, bypassing the legacy tick-based throttle queue entirely
- **Async/non-blocking chunks** — When running on Paper/Folia 1.21+, chunk loads no longer compete for tick time
- **Backward compatible** — Legacy throttle queue is still available for older servers or when explicitly configured
- **Smart auto-detection** — Defaults to `auto-detect` mode, gracefully falls back to legacy queue if needed
- **Configurable via** `chunk-loading.use-paper-async-api` in rtp.yml
### Biome Filtering Enhancements
- **Master switch for biome system** — New `biomes.enabled` setting disables the entire biome infrastructure (search, cache, rare biome tracking)
- **Master switch for include/exclude filters** — New `biome-filtering.enabled` separate from the overall biome system
- **Automatic filter-aware performance budgets** — When include/exclude biome filters are active but no explicit budget is configured, tighter limits are applied automatically (100ms wall-clock, 10 chunk-loads)
- **New performance-budget section** — Cleaner configuration path for search budgets (`biome-filtering.performance-budget`)
- **Better timeout tracking** — Biome filter timeouts are now monitored and reported in performance stats
- **Async-mode toggle** — Serialize biome searches through a dedicated executor thread instead of the common fork-join pool when `async-mode: false`
### Rare Biome Hotspot Persistence
- **MySQL-backed hotspot storage** — Persist discovered rare-biome hotspots across restarts and share them between network nodes
- **HikariCP connection pool** — Efficient, non-blocking database operations
- **Background loading** — Hotspots are loaded asynchronously on startup
- **Configurable persistence backend** — Switch between in-memory only (`none`) or MySQL (`mysql`)
- **Automatic table creation** — Database schema is initialized automatically
## 🔧 Configuration Changes
### New Configuration Files
- `plugins/EzRTP/performance.yml` — Performance monitoring and warning settings
- `plugins/EzRTP/unsafe-location-monitoring.yml` — Unsafe location rejection tracking and warnings
### rtp.yml Changes
- **`biomes.enabled`** (new) — Master switch for the entire biome system (default: `true`)
- **`biome-filtering.enabled`** (new) — Separate toggle for include/exclude biome filters (default: `true`)
- **`biome-filtering.performance-budget`** (new, preferred) — Search budget configuration moved here for clarity
- **`search.*`** (legacy path still works) — Old budget location, now aliases to new path
- **`chunk-loading.use-paper-async-api`** (new) — Auto-detect or explicitly enable/disable Paper async chunk loading (default: `auto-detect`)
- **`chunk-loading.legacy-throttle`** (new) — Nested section for old throttle settings, replaces flat `enabled/interval-ticks/max-chunks-per-tick`
- **`heatmap.enabled`** — Toggle heatmap feature per world (was implicit before)
- **`safety.reject-liquid-above-nether`** (new, default: `true`) — Reject locations with lava above in the Nether
- **`safety.reject-liquid-above-overworld`** (new, default: `true`) — Reject locations with water above in the Overworld
### Network Configuration (`network.yml`)
- Moved to `plugins/EzRTP/network/` namespace for better organization
### Dependency Updates
- **Bukkit/Paper actions** — Updated from v4 to v6
- **Java compiler** — Updated to 3.15.0
- **bstats** — Updated from 3.0.2 to 3.2.1
- **WorldGuard** — Updated from 7.0.9 to 7.0.16
- **PlaceholderAPI** — Updated from 2.11.7 to 2.12.2
- **Adventure** — Multiple library versions updated to 4.26.1
- **HikariCP 7.0.2** — New dependency for MySQL hotspot storage
- **JUnit & Mockito** — Updated test dependencies
## 🐛 Bug Fixes & Improvements
### GriefPrevention Compatibility
- Fixed reflection fallback to handle multiple `getClaimAt()` method signatures across GriefPrevention versions
### Import/Package Reorganization
- Configuration classes reorganized into semantic packages: `biome.*`, `effects.*`, `network.*`, `safety.*`, `teleport.*`, `gui.*`, `performance.*`
- Old import paths still work through backwards-compatible re-exports (zero breaking changes)
### Code Quality
- Introduced `ConfigurationDefaults` class to centralize all default numeric constants
- Improved documentation and JavaDoc throughout
- Better error handling and logging in reflection-based code (ChunkyAPI, GriefPrevention, PlaceholderAPI)
### Platform Abstraction
- **Enhanced PlatformScheduler** — New methods `executeGlobal()`, `executeGlobalDelayed()`, `executeRegionDelayed()` for cleaner code
- **Folia compatibility** — All scheduler calls now route correctly on Folia's regionalized threads
- **Centralized capability detection** — New `PlatformRuntimeCapabilitiesDetector.isPaper121PlusAsync()` for version-aware optimization
### API Extensions
- `RandomTeleportService` now implements the new `com.skyblockexp.ezrtp.api.TeleportService` interface for type-safe service registration
## 📊 New Statistics & Metrics
### Tracked in `RtpStatistics`
- **Timing percentiles** — P50, P75, P90, P95, P99 milliseconds
- **Min/max operation times** — Absolute bounds across the ring buffer
- **Slow operation count** — Number of RTPs exceeding the slow-threshold
- **Chunk loads breakdown** — Total, async, and sync counts
- **Biome rejection counts** — Total rejections and per-RTP max
- **Biome filter timeouts** — Number of times a search was terminated due to biome rejection limit
### bStats Charts (New)
- `unsafe_location_cause` — Top rejection cause (pie chart)
## 🎮 New Commands
### `/rtp stats performance`
- Shows real-time performance metrics including response times, cache hit rate, chunk loading breakdown, and recommendations
### `/rtp unsafe-stats`
- Shows all-time unsafe location rejection statistics broken down by cause
## 📝 Configuration Validation
### New Warnings
- **Missing protection providers** — Single consolidated warning when all configured protection plugins are unavailable
- **Heatmap disabled check** — `/rtp heatmap` now validates that `heatmap.enabled: true` before proceeding
- **Chunky reflection fallback** — Graceful degradation if Chunky API changes or is unavailable
## ♻️ Removed/Deprecated
- `ChunkLoadingSettings` legacy flat-format constructors are deprecated (but still work)
- **No breaking changes to public APIs** — All existing plugin code continues to function
---
## For Server Owners
**Update Guide:**
1. Back up your `plugins/EzRTP/` folder
2. Replace the EzRTP .jar file
3. Restart the server (config files will be auto-generated)
4. Optionally enable performance or unsafe-location monitoring in the new .yml files
5. For Paper 1.21+ users, chunk-loading will automatically switch to async mode (no config needed)
**Recommendations:**
- **Enable performance monitoring** if you want insight into RTP responsiveness and cache efficiency
- **Enable unsafe-location monitoring** if you're debugging biome filter issues or want to understand rejection patterns
- **Upgrade to Paper 1.21+** to get true non-blocking chunk loading (no configuration required; auto-detected)
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }