Tags
Creators
Details
2.0.0
Compatibility
Changes
Added
- Folia support - the plugin now runs on Folia (marked
folia-supported: trueinplugin.yml). Folia'sGlobalRegionScheduleris used automatically when detected at runtime; Paper/Spigot continue to use the Bukkit scheduler. compat/package hierarchy - clean OOP abstraction layer:compat.platform.PlatformDetector- detects Folia vs. Paper/Spigot at startup viaRegionizedServerclass presence.compat.scheduler.SchedulerAdapter/TaskHandle- platform-agnostic scheduler interface (runTask,runTaskTimer,runTaskLater,runTaskAsync).compat.scheduler.BukkitSchedulerAdapter-SchedulerAdapterbacked byBukkitScheduler(Paper/Spigot).compat.scheduler.FoliaSchedulerAdapter-SchedulerAdapterbacked byGlobalRegionScheduler(Folia); only class-loaded when Folia is detected.compat.scheduler.SchedulerAdapterFactory- chooses the correct adapter with graceful fallback if Folia classes are missing.compat.version.ServerVersionUtil- canonical location for runtime Minecraft version detection (replacesutil.ServerVersionUtil).compat.material.MaterialCompat- canonical location for cross-version material resolution (replacesutil.MaterialCompat).
- Startup platform log -
PluginBootstrapnow logs the active scheduler adapter class on enable (e.g.Scheduler: BukkitSchedulerAdapter).
Changed
-
util.ServerVersionUtilandutil.MaterialCompatare now@Deprecateddelegation stubs that forward to their canonicalcompat.*counterparts; they will be removed in a future release. -
All internal scheduler usages (
CountdownManager,FireworkShowManager,PatternScheduler,ChatInputListener, alllistener.actions.*GUI action classes,SpigotIntegration,SpigotUpdateChecker) now go throughSchedulerAdapterinstead ofBukkit.getScheduler()/BukkitRunnabledirectly. -
Scoreboard API modernised -
ScoreboardDisplaynow delegates tocompat.scoreboard.ScoreboardCompat. On Paper 1.20.3+ (Criteria.DUMMYavailable) the modernregisterNewObjective(String, Criteria, Component)overload is used; older builds fall back to the legacy string overload. The deprecatedScoreboard.resetScores(String)calls are replaced by objective unregister/re-register viaScoreboardCompat.resetObjective. -
Title API modernised -
TitleDisplaynow delegates tocompat.title.TitleCompat. On Paper 1.18+ the AdventurePlayer.showTitle(Title)/Player.clearTitle()APIs are preferred over the deprecatedsendTitle(String...)/resetTitle().TitleValidatornow also acceptsshowTitleas a valid title capability. A Spigot/legacy string fallback is retained. -
Per-player notification targeting -
NotificationBuilder.players(Collection<Player>)restricts a notification to specific players.EzCountdownApi.sendNotification(Notification, Collection<Player>)provides an inline alternative without building aNotificationfirst. -
Countdown.isVisibleTo(Player)- centralises per-player visibility logic (permission gate + target-player set) in one method; all display handlers now use it instead of duplicated inline checks. -
CountdownBuilder.targetPlayers(Collection<Player>)- restrict a persistent countdown's display to specific players. -
Developer-friendly exception hierarchy - new
com.skyblockexp.ezcountdown.api.exceptionpackage:EzCountdownException- base unchecked exception; catch this for all EzCountdown API errors.CountdownNotFoundException- thrown when referencing a countdown name that does not exist; carriesgetCountdownName().DuplicateCountdownException- thrown when creating a countdown whose name already exists; carriesgetCountdownName().InvalidConfigurationException- thrown byNotificationBuilder.build()and future builder validators when configuration is invalid; replaces the genericIllegalStateException.
-
api-versionbumped to1.18inplugin.yml; minimum supported Minecraft version is Paper/Spigot 1.18. Dialog display continues to require Paper 1.21.7+. -
Broadened Java compatibility - release JARs now target Java 17 bytecode (previously Java 21), so the plugin runs on Paper 1.18 - 1.20.4 (Java 17) as well as Paper 1.20.5+ (Java 21). The
jdk21Maven profile also targets Java 17 bytecode. -
ServerVersionUtil- new utility class (com.skyblockexp.ezcountdown.util.ServerVersionUtil) for runtime Minecraft version detection; enables future conditional feature gating without hard API dependencies. -
Startup guard -
onEnablenow logs the detected MC and Java version and disables the plugin with a clear error message if the server is too old (MC < 1.18 or Java < 17).
Changed
- All display handlers (
ActionBarDisplay,TitleDisplay,ChatDisplay,BossBarDisplay,ScoreboardDisplay,DialogDisplay) usecountdown.isVisibleTo(player)instead of duplicated inline permission checks. NotificationBuilder.build()now throwsInvalidConfigurationException(a subclass ofEzCountdownException) instead of a plainIllegalStateException.ScoreboardDisplaycatch blocks now includeNoSuchMethodErrorso the scoreboard falls back to chat if the String-criteriaregisterNewObjectiveoverload is ever removed in a future Paper build.- Project version bumped from
1.4.3to2.0.0.
Fixed
- DURATION countdown resets to full duration on
/countdown reload-resumeRunningCountdowns()previously calledhandler.onStart(), which always setstargetInstanttonow + fullDuration, discarding thetarget_epochsaved in storage. It now callshandler.ensureTarget()instead, which is a no-op when a target is already present. The same guard was added to the legacy fallback path for handler-less countdown types. End-commands that fired once before a reload will no longer fire again unexpectedly due to the countdown silently restarting.
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:rCku0I4l:4VLVIdnX"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:rCku0I4l:4VLVIdnX"
}

