AquaLib
The boring parts of a Bukkit plugin, solved once. Config mapping, item building, GUI plumbing, a Folia-safe scheduler and the HEX/gradient colour engine used across every Aquatic project. No runtime dependency on any of our plugins — drop it into your own project and use it standalone.
| Group | com.github.aquatic-studios |
| Artifact | AquaLib |
| Repository | JitPack |
| MC | 1.16+ (HEX colours required) |
| Java | 17+ |
| Platform | Bukkit / Spigot / Paper / Folia |
If you ship AquaLib inside a plugin you must relocate it. Two plugins bundling the same unrelocated classes will fight over the classloader. See Shading.
Installation
Gradle (Kotlin)
repositories {
maven("https://jitpack.io")
}
dependencies {
implementation("com.github.aquatic-studios:AquaLib:1.6.0")
}Shading
Relocate com.aquaticstudios.aqualib into your own namespace.
Gradle Shadow
plugins {
id("com.gradleup.shadow") version "8.3.5"
}
tasks {
shadowJar {
relocate("com.aquaticstudios.aqualib", "com.example.myplugin.libs.aqualib")
minimize()
}
}Colours
import com.aquaticstudios.aqualib.text.Colors;
Component line = Colors.parse("&ecff&lAqua�a84ffLib &8» &7ready");
Component grad = Colors.parse("<gradient:#38ecff:#0a84ff>Smooth</gradient>");| Input | Supported since |
|---|---|
&a, &l legacy codes | 1.0.0 |
&#rrggbb HEX | 1.0.0 |
<gradient:#a:#b>text</gradient> | 1.2.0 |
<rainbow>text</rainbow> | 1.5.0 |
Items
import com.aquaticstudios.aqualib.item.ItemBuilder;
ItemStack star = ItemBuilder.of(Material.NETHER_STAR)
.name("&ecff&lLegend Tag")
.lore("&7Animated gradient tag.", "", "&ecffClick to equip")
.glow(true)
.flags(ItemFlag.HIDE_ATTRIBUTES)
.amount(1)
.build();Every setter accepts the same colour syntax as Colors.parse.
Config mapping
Annotate a class, get a typed config with defaults, comments and automatic migration.
import com.aquaticstudios.aqualib.config.*;
@ConfigFile("config.yml")
public final class Settings {
@Comment("Prefix prepended to every plugin message.")
@Key("settings.prefix")
public String prefix = "&ecff&lAqua &8» &r";
@Key("settings.check-updates")
public boolean checkUpdates = true;
@Key("broadcast.cooldown")
public int cooldown = 3;
}Settings settings = ConfigLoader.load(this, Settings.class);
getLogger().info("Cooldown: " + settings.cooldown);New fields are appended to the existing file on the next boot, keeping the user values and your comments intact.
Scheduling
One API that behaves correctly on both Paper and Folia.
import com.aquaticstudios.aqualib.scheduler.Schedulers;
Schedulers.global(this).runLater(() -> broadcast(), 20L);
Schedulers.entity(player).run(() -> player.setHealth(20.0));
Schedulers.async(this).run(() -> fetchSkin(uuid));On Paper these map to the classic BukkitScheduler. On Folia they map to the global, entity and
async schedulers respectively. Your code does not change.
Versioning
Semantic versioning. Anything under com.aquaticstudios.aqualib.internal is not public API and can
change in any release.