Tags
Creators
Details
4.0.0-SNAPSHOT+1-folia
Compatibility
Changes
Added
-
Full port of all features from Bukkit
4.0.0-SNAPSHOT+4:- Subcommand system:
/cc help | effect | gui | chance | language | reload - Multiple firework styles + independent per‑style probabilities (auto-compensated to 100%) + weighted random selection on trigger
- Graphical GUI management (list / edit / pagination / add / delete / adjust probability / preview)
- Paged Help with clickable chat pagination
- Parallel GeoIP lookup across multiple APIs
- Config migration + backup (
config-version) - 18 language files (
xx_yycode format, standardized to 99 keys) debuglogging toggle
- Subcommand system:
-
Folia thread model adaptation (Folia has no main thread;
Bukkit.getScheduler()does not exist and throws exceptions when invoked):- New
creeperconfetti.util.Schedulersto wrap four Folia schedulers uniformly:
- New
| Usage | Folia API |
|---|---|
| Entity-owned region (firework detonation, GUI open) | entity.getScheduler().run / runDelayed |
| Location-owned region | Bukkit.getRegionScheduler() |
| Global thread (≈ main thread, for command/event registration) | Bukkit.getGlobalRegionScheduler() |
| Async (GeoIP network requests) | Bukkit.getAsyncScheduler() |
-
Replaced all six Bukkit scheduler calls:
FireworkUtil.spawnAndDetonate: Changed to detonate with a 1-tick delay on the firework entity’s region schedulerCreeperExplodeListener: Same as above (explosion event already fires on the creeper’s region thread)BaseGui.openLater: Open inventory on the player entity’s region scheduler (inventory opening must happen on the player’s region thread)- Region lookup in
LanguageManager:runAsync+runGlobal(switch back to global thread to modify Bukkit state after lookup completes) - Language reload callback in
LanguageCommand: Changed torunGlobal
-
Cross-region thread safety (multiple region threads concurrently access shared plugin state under Folia):
- All public methods in
FireworkStyleManagerwrapped withsynchronized(preventsConcurrentModificationExceptionfrom concurrentLinkedHashMapread/write when region A edits styles while a creeper explodes in region B) LanguageManager.getMessage / getConsoleMessage / loadMessagesmarkedsynchronized;currentLanguagechanged tovolatileconfetti_chanceanddebugconverted to volatile cached fields, avoiding unsafeFileConfigurationreads during explosions on region threads
- All public methods in
-
plugin.ymldeclaresfolia-supported: true(Folia rejects plugin loading without this field).
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:zOtyOPVB:C3SspKHM"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:zOtyOPVB:C3SspKHM"
}

