API
Reading the effect catalogue and its categories, a player's chosen effect, their shortlist and particle setting, and the effects bound to bows.
ArrowsService is what another plugin reads and drives ExyliaArrows through: the catalogue and its
categories, the effect a player chose, their shortlist and particle setting, and the effects bound to
bows.
ExyliaAPI.get(ArrowsService.class).ifPresent(arrows -> {
arrows.select(player, "storm");
arrows.effectItem("storm").ifPresent(item -> player.getInventory().addItem(item));
});The artifact, the repository and the plugin.yml line are the same for every Exylia plugin and live
on the public API page.
Everything is addressed by effect id, matched without regard to case. An id the catalogue does
not declare is not an error — a reload can remove one while a crate still hands it out — so lookups
answer empty and writes answer false.
The catalogue
| Method | What it does |
|---|---|
effects() | Every effect the server declares, in the order a menu draws them. A snapshot: fine for building a shop, wasteful in a loop. |
effect(String effectId) | One effect as an Optional<ArrowEffect>. Empty when the catalogue declares no such id. |
exists(String effectId) | Whether the catalogue declares that id. |
categories() | Every category, in the order the menu draws its tabs. |
category(String categoryId) | One category as an Optional<ArrowCategory>. Empty when the catalogue declares no such id. |
effectsIn(String categoryId) | The effects in one category, in menu order. Empty when the category does not exist. |
Permissions
| Method | What it does |
|---|---|
canUse(Player, String effectId) | Whether they may use the effect. |
Answers by the server's own rule: the effect's node, the node for its whole category, the wildcard, or the setting that turns permissions off entirely. A shop asking gets the same answer the menu would give, not a raw permission check.
What the player chose
| Method | What it does |
|---|---|
mode() | Where the effects this server plays come from, as an EffectMode. |
selected(UUID player) | Their chosen effect id, as an Optional<String>. Empty when they chose none, the menu is off, or their row is still being read. |
select(Player, String effectId) | Sets the effect that follows them. true when it was stored. |
clear(Player) | Takes their chosen effect off. |
select is a set rather than a toggle — running it twice leaves the effect on. It is not gated by
permission, because the server owner's own setting says it should not be: an effect handed out by a
crate or a reward is owned whether or not a node was ever granted for it. That is the same rule
ExyliaArmorTrims follows and the opposite of ExyliaArmorSkin. Ask canUse first when you do want the
permission to decide.
Favourites
| Method | What it does |
|---|---|
favourites(UUID player) | The effect ids they starred, in the order they starred them. Empty when they starred none or are still being read. |
isFavourite(UUID player, String effectId) | Whether one effect is starred. |
toggleFavourite(Player, String effectId) | Stars an effect, or unstars it when it is already starred. true when the id named an effect that exists. |
clearFavourites(Player) | Unstars everything. |
The shortlist keeps the player's own order rather than the catalogue's — somebody built it, and
re-sorting it takes that away. toggleFavourite is deliberately a toggle rather than a pair of
methods: the star is one control with two states, and a caller that had to read the state first would
race the player clicking it.
Particle visibility
| Method | What it does |
|---|---|
visibility(UUID player) | Who currently sees their arrow particles. ParticleVisibility.ALL when they never changed it or are still being read. |
setVisibility(Player, ParticleVisibility) | Stores who sees them. |
Effects on items
| Method | What it does |
|---|---|
boundTo(ItemStack bow) | The effect id bound to that bow, crossbow or trident, as an Optional<String>. Empty when it carries none. |
bind(ItemStack bow, String effectId) | Binds an effect to the bow in place, keeping everything else it had. Refused when the item is not something an effect can be bound to, or when the effect declares itself not to fit it. |
unbind(ItemStack bow) | Takes the effect off and gives nothing back. true when an effect was there. |
effectItem(String effectId) | An effect token ready to be given out, as an Optional<ItemStack>. Empty when the catalogue declares no such effect. |
isEffectItem(ItemStack) | Whether an item is one of this plugin's effect tokens. |
Ask isEffectItem before a container, a shop or a trade treats a stack as ordinary loot: a token is
drawn as whatever suits what it carries and is not the material it looks like.
Types
ArrowEffect — id, categoryId, name (colour codes still in it), permission (the node
granting this one effect) and description (the owner's own words, line breaks and all). What the
effect draws is deliberately absent: it is a compiled sequence belonging to the plugin that plays
it.
ArrowCategory — id, name, permission. Its node grants every effect inside it at once,
which is how a rank is sold as "every storm effect" without listing them one by one.
EffectMode — where a played effect comes from: PLAYER (only what the player picked; a bow
carries nothing), BOW (only what is bound to the bow; the menu chooses nothing) or BOTH.
usesBows() and usesMenu() answer without a switch. Worth asking before writing anything: the half
a server does not use answers false or empty rather than throwing, so an integration written for
both runs on either.
ParticleVisibility — ALL, NONE, SELF_ONLY, OTHERS_ONLY. A player's own setting, not a
server one. The label each mode is shown under is written by the server owner and is not carried
here: a constant is an identity, not a name.
Everything returning a value reads the plugin's cache and is safe from a menu redraw or a placeholder — a player who has not finished loading reads as one who chose nothing, which is why every read answers rather than waits. Everything that changes a player's choice writes to the database, so call those on the main thread and no more often than a player could.
What it does not expose
No events: ExyliaArrows publishes none. Menu openers, the effect editor, the compiled particle sequences and raw configuration rows are left out on purpose — a public contract cannot be broken later, so it carries what an integration needs and nothing that only made sense inside one version.
If something you need is genuinely missing, ask on Discord.
Something missing on this page? Tell us on Discord