All versions
4.5-rls
Release
Final fixes6 months ago 170
Compatibility
Minecraft: Java Edition
26.2
26.1.x
1.21.x
1.20.x
1.19.x
1.18.x
1.17.x
1.16.x
1.15.x
1.14.x
1.13.x
1.12.x
1.11.x
1.10.x
1.9.x
1.8.x
1.7.9–1.7.10
Platforms
Bukkit
Folia
Paper
Purpur
Spigot
Changes
Added
- Folia scheduler support with automatic fallback to Bukkit scheduler
- SQLite ON CONFLICT detection for better UPSERT performance
- UUID-based write locks for thread-safe player data operations
- Player save queue (
pendingSaves) to serialize async database writes per UUID - Offline player name caching to reduce I/O operations during batch processing
- YAML save debouncing with resettable timer (
scheduleYamlSave) - Atomic reference for
nameToUUIDsanduuidToNamemaps for safe reload - Legacy YAML format detection and migration support (
uuid: GAMEMODE) - Support for setting gamemode for players who have never joined the server
GamemodeChangeEventcustom event for API integration-all,-online,-offlinebatch operation flags- Database transaction support for batch offline player updates
- Automatic config.yml key merging with missing defaults preservation
- Connection retry mechanism with configurable attempts and delay
- Debug logging controlled by config option
Fixed
- NPE in
onDisable()whenstorageTypeis not"yaml"andyamlCacheis null - Race condition in
onPlayerJoinwhere async save could overwrite recently set gamemode - SQL operation silent failure - now logs error after max retry attempts
- Write lock timeout now logs debug message instead of failing silently
- Skipped offline players during batch operations now logged with warning count
- Config merge now properly adds missing keys without overwriting existing values
- Migration now handles both legacy (flat) and modern (nested) YAML formats
Changed
- Replaced
pendingSavesSet<String>withMap<UUID, CompletableFuture<Void>>for per-UUID queuing - Refactored
tryWriteLockpattern intowithWriteLockhelper method - Optimized
processOfflinePlayersDatawith name cache and early empty check - Cached UPSERT SQL generation to avoid repeated ON CONFLICT detection
- Message placeholder replacement now uses
Matcher.quoteReplacement()to escape$and\ - Folia reflection now uses
Consumer.classwith proper generic erasure handling savePlayerModeDirectnow updates memory cache immediately before async DB write- Batch migration now uses incremental
executeBatch()to avoid memory issues
Removed
- Legacy
yamlCache.set(uuid.toString(), mode.name())flat format write - Redundant
saveYamlCache()call when using database storage - Unused
SAVE_DELAYfield from earlier versions
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:J0B80Y0Q:1tKit9tx"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:J0B80Y0Q:1tKit9tx"
}

