Content generated with AI — it may contain mistakes.

Referenceguide

Public API

One artifact the whole Exylia suite answers through: add it, look a service up, listen for its events.

Every Exylia plugin publishes its API the same way. There is one artifact to add, one class to call, and one rule to follow — and once you know it for one plugin you know it for all of them.

Adding it to your build

The API is published from the ExyliaLib repository through JitPack.

build.gradle
repositories {
    maven { url 'https://jitpack.io' }
}
 
dependencies {
    compileOnly 'com.github.DiGround-s.ExyliaLib:exylia-api:v1.113.0'
}
build.gradle.kts
repositories {
    maven("https://jitpack.io")
}
 
dependencies {
    compileOnly("com.github.DiGround-s.ExyliaLib:exylia-api:v1.113.0")
}
pom.xml
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>
 
<dependencies>
    <dependency>
        <groupId>com.github.DiGround-s.ExyliaLib</groupId>
        <artifactId>exylia-api</artifactId>
        <version>v1.113.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

The version is the ExyliaLib release tag, v included. Sources and javadoc are published alongside it, so your IDE shows the documentation for every method without leaving the editor.

compileOnly is not a style choice

compileOnly — provided in Maven — is required, and shading the artifact into your own jar breaks it. These classes already ship inside ExyliaLib.jar on the server. A second copy in your jar is loaded by your classloader, which makes it a different class than the one the plugins implement, and every lookup returns nothing. There is no error message; it simply never finds anything.

Declaring the library

ExyliaLib has to be enabled before you, and your plugin has to be allowed to see its classes. One line in your plugin.yml does both:

plugin.yml
depend: [ ExyliaLib ]

Use softdepend instead if your plugin should still load on a server without ExyliaLib. Then guard every call with the Optional the lookup already hands you.

Looking a service up

Everything goes through net.exylia.lib.api.ExyliaAPI.

ExyliaAPI.get(ClansService.class)
         .flatMap(clans -> clans.clanOf(player.getUniqueId()))
         .ifPresent(clan -> player.sendMessage("Clan: " + clan.name()));
CallFor
get(Service.class)A soft integration. Returns Optional, empty when the plugin is absent, disabled, or still enabling.
require(Service.class)A hard depend on the plugin behind the service. Throws IllegalStateException when it is not there.
isAvailable(Service.class)A capability check, without unwrapping anything.
Resolve where you use it, not in onEnable

A service registers when its plugin enables, and server load order is not yours to choose. Looking one up inside your own onEnable may well ask before the other plugin has started. Resolve it at the point of use — the lookup is a map read — or from ServerLoadEvent.

Listening for events

Plugins that have something worth reacting to publish real Bukkit events, in the same artifact, under net.exylia.lib.api.<plugin>.event. They are registered like any other listener:

@EventHandler
public void onKitClaim(KitClaimEvent event) {
    if (isTournamentRunning()) event.setCancelled(true);
}

Cancelling means the action does not happen and no message is sent — telling the player why is yours to do. Each event's javadoc says whether an uncancelled event guarantees the action went through: some do, and some sit in front of a step that can still fail, such as a payment or a teleport warmup a player can walk out of.

Why the contract lives in the library

Worth knowing, because it explains the compileOnly rule and why there is one artifact rather than twenty.

Every Exylia plugin ships as a loader jar: the server loads a small loader, which decrypts the real plugin into a classloader of its own. Bukkit's dependency delegation reaches that loader and stops there — so an interface shipped inside a plugin is invisible to every other plugin, whatever the plugin.yml files say, and a copy shipped in both is two unrelated classes.

ExyliaLib is the one jar every plugin on the server can already see. So the contract lives there, and exylia-api is the same classes packaged for you to compile against.

The services

ServicePluginPackage
AimTrainerServiceExyliaAimTrainernet.exylia.lib.api.aimtrainer
ArmorSkinServiceExyliaArmorSkinnet.exylia.lib.api.armorskin
ArmorTrimServiceExyliaArmorTrimsnet.exylia.lib.api.armortrims
ArrowsServiceExyliaArrowsnet.exylia.lib.api.arrows
CaptureServiceExyliaCapturenet.exylia.lib.api.capture
ChatServiceExyliaChatCosmeticsnet.exylia.lib.api.chatcosmetics
ClansServiceExyliaClansnet.exylia.lib.api.clans
ClassesServiceExyliaClassesnet.exylia.lib.api.classes
CosmeticsServiceExyliaChatCosmeticsnet.exylia.lib.api.chatcosmetics
EventsServiceExyliaEventsnet.exylia.lib.api.events
FfaServiceExyliaFFAnet.exylia.lib.api.ffa
HitEffectServiceExyliaHitEffectnet.exylia.lib.api.hiteffect
KillEffectServiceExyliaKillEffectnet.exylia.lib.api.killeffect
PracticeBotServiceExyliaPracticeBotnet.exylia.lib.api.practicebot
PracticeServiceExyliaPracticeCorenet.exylia.lib.api.practice
SandBoxServiceExyliaSandBoxnet.exylia.lib.api.sandbox
ShieldsServiceExyliaShieldsnet.exylia.lib.api.shields
StaffServiceExyliaStaffnet.exylia.lib.api.staff
SurvivalServiceExyliaSurvivalCorenet.exylia.lib.api.survival
TotemTrainerServiceExyliaTotemTrainernet.exylia.lib.api.totemtrainer

EventsService also carries net.exylia.lib.api.events.custom, the one place in the artifact where a plugin declares something for another to run rather than reading it: a minigame of its own, set up and played by ExyliaEvents. See ExyliaEvents · Registering your own minigame.

Each plugin's own API page documents what its service exposes and what it deliberately does not.

What is not there

Every service is curated rather than a mirror of the plugin's internals. Editor flows, administrative writes and raw configuration rows are left out on purpose: a public contract cannot be broken later, so it holds what an integration genuinely needs and nothing that only made sense inside one version of one plugin. A few services do open a player's own screens — an NPC or a hotbar item is a real reason to — and each plugin's API page says which.

If something you need is missing, ask on Discord rather than reaching for reflection — a method added to a service is a minor release, and reflection into a loader plugin does not work in the first place.

Versioning

exylia-api follows semantic versioning independently of ExyliaLib's own version. New methods and new services are minor releases and never break you. Removing or changing one would be a major release, which is why the surface is curated before publishing rather than after.

Compiling against an older tag than the server runs is fine. The reverse is not: a method added in a newer API is not in an older ExyliaLib.jar, and finds nothing at runtime.

Something missing on this page? Tell us on Discord