Guide to the AuraSkills API
The AuraSkills API allows developers to interact with the plugin, integrate with an existing plugin, or register content (custom skills, stats, abilities).
The API consists of just the api
and api-bukkit
sub-modules. This allows API methods to be stable across versions and prevents the use of unstable internal methods.
Javadocs are available here.
Release versions are published to the Maven central repository.
Groovy DSL:
Kotlin DSL:
Most API classes are accessible through the AuraSkillsApi interface accessed using the following static method.
In very limited situations where the API requires Bukkit classes, such as the ItemManager and Regions API, you will have to obtain an instance of the AuraSkillsBukkit interface:
Any use of the auraSkills
variable name below refers to the AuraSkillsApi
instance.
Player skill information is available through the SkillsUser
interface, which is obtained from the API instance:
While the method accepts a uuid, only online players will have their skill data loaded. Offline players will still return a SkillsUser
object, but will have all values set to default ones and modifying values will not work.
You can get and set a user's skill level using the user methods and the Skills
enum for default skills. For example:
Getting and adding skill XP is very similar:
Getting a player's stat level is simple using the method and the Stats
enum.
Adding stat levels is more complex, since stat levels aren't stored directly. Instead, there a system of stat modifiers which associates a unique name to a stat increase so it can be tracked and removed later.
Getting and setting mana is very simple:
An easier way to consume mana for things like activating mana abilities or casting spells is using the consumeMana
method. This returns true if the user has enough mana and mana was successfully removed, and false if mana could not be removed. It also automatically sends a "Not enough mana" message to the action bar.
The API has many events to interact with the plugin. These are registered just like regular Bukkit events.
The following is a list of available events. This may not always be up-to-date, so see the source code for all the events.
LootDropEvent
- Calls when the plugin drops/modifies item loot. Includes both multiplier abilities and Fishing/Excavation loot tables. Use getCause()
to get the reason for the drop.
SkillsLoadEvent
- Calls when the plugin has fully finished loading, usually on the first tick of the server. Use this event when accessing anything related to skills, stats, etc on server startup instead of in onEnable
, since skills won't be loaded yet then.
ManaAbilityActivateEvent
- Calls when a player activates a mana ability.
ManaAbilityRefreshEvent
- Calls when a player is able to use a mana ability again (cooldown reaches 0)
ManaRegenerateEvent
- Calls when a player regenerates mana naturally.
SkillLevelUpEvent
- Calls when a player levels up a skill.
XpGainEvent
- Calls when a player gains skill XP.
CustomRegenEvent
- Calls when a player regenerates health if custom regen mechanics are enabled.
The global registry is used to get any Skill, Stat, Ability, etc instance by its NamespacedId. This allows you to parse content from a name that supports custom content. Use AuraSkillsApi#getGlobalRegistry
to get the registry. This is a read-only interface, to register your own custom content, see #custom-content.
To register custom content, you must first obtain a NamespacedRegistry that identifies your plugin and the directory from which to load content files (including skills.yml, rewards, sources, etc).
The first argument of useRegistry
is the name of your plugin registering the custom content (it will be forced to lowercase). This is the namespace part of all content that is identified by a NamespacedId, and is used in config files like skills.yml, abilities.yml, etc.
The second argument of useRegistry
is a Java File object representing the content directory. Some things like sources and rewards cannot be registered through code alone and must be done through config files that are automatically detected and loaded from the content directory. A good choice is just the plugin's data folder, which is accessed from Plugin#getDataFolder()
.
The format for content files is the same as the main AuraSkills plugin, as your content files are merged together with the main plugin's config files when loading skills, stats, and abilities. For example, you can reference auraskills/
namespaced abilities in your skills.yml file, and yourplugin/
namespaced abilities can be used in the AuraSkills skills.yml file.
To create a custom stat, use the CustomStat.builder
static method to get an instance of CustomStatBuilder
. You must pass in a NamespacedId
using NamespacedId.of
to identify the stat. Then register the stat with the NamespacedRegistry
.
Stats on their own don't represent any game mechanics or attributes. Every stat must also have at least one trait that actually implements functionality. Use the CustomTrait.builder
to get a CustomTraitBuilder
to create a trait. This CustomTrait
is then passed into CustomStatBuilder#trait
to link it to the stat. You can also pass in a default trait from the Traits
enum if you want to simply split up stats.
The example below shows creating a new dexterity stat with a dodge chance trait adding functionality to evade attacks. We create new classes and assign the trait and stat to static constants for easier access.
You must then register the CustomTrait and CustomStat in your plugin's onEnable:
Replace "pluginname" with the name of your plugin in lowercase. The name passed into NamespacedId.of
must match the one passed in AuraSkillsApi#useRegistry
.
The above code only registers the existence and display elements of the stat without any gameplay functionality. If your stat only uses existing traits, this is all you need. However, if are creating a new trait like the example above, you must add additional code to actually implement your trait's functionality.
To implement your trait functionality, create a new class that implements BukkitTraitHandler
:
Finally, register your BukkitTraitHandler
in onEnable:
Calling registerTraitHandler automatically registers any Bukkit events if the class implements Listener.
To make your stat and trait configurable by users of your plugin, create a stats.yml
file in your plugin's content directory that you linked to the NamespacedRegistry
used to register your traits/stats.
Here is an example stats.yml
for the Dexterity/Dodge Chance example above:
You are responsible for generating the stats.yml
file in the user's folder using Plugin#saveResource
.
To create a custom skill, get an instance of the builder using CustomSkill.builder
and pass in a NamespacedId
using NamespacedId.of
. Then register the skill with the NamspacedRegistry
.
The following is an example for creating a Trading skill that gives XP when trading with villagers. We create a new CustomSkills
class with a static constant to hold the reference to the skill instance for easier access.
Then, register the skill in your plugin's onEnable:
To add ways to gain XP for a custom skill, create a sources file with the same format as the AuraSkills sources files. For our example, create a file at sources/trading.yml
.
If your custom skill's XP sources use existing source types available in default skills (such as breaking blocks, killing a mob, tracking a statistic, etc), then you just need to add configured sources of the existing types to the file. See Sources for how to add existing source types.
In our case, there is no existing source type that handles trading with villagers, so we will need to create our own using the API.
First, create a class that extends CustomSource
to hold the configurable data of your source. In this case for simplicty, our only parameter will be the number of emeralds transacted in the trade, so we just need to add a configurable multiplier for this value. Keep the SourceValues constructor argument in your constructor and add your parameters to the end of it.
Then, you need to register your source type and create a parser to deserialize the source from configuration. Use NamespacedRegistry#registerSourceType
to register the name and parser of your source.
The first argument, name, is a lowercase name for your source used to construct its NamspacedId used as the type
key in the sources config. If you pass in trading
as the name, you would use type: pluginname/trading
in the sources config.
The second argument accepts an instance of XpSourceParser
where the type parameter is your CustomSource
class. You can create a new class, or use a lambda like in this example:
The source
argument of the lambda is a ConfigurationNode
from Configurate that contains the keys and values from the configuration section of the source to load. The context
argument is a SourceContext
that contains useful parsing methods for enforcing required keys or getting pluralized values. You also need to use context.parseValues(source)
to get the SourceValues
object to pass as the first argument of your source type constructor. This parses things like the name, xp, and display_name of the source for you, so you only need to implement parsing of your custom options.
To make your source actually give XP, you need to implement a leveler that listens to the proper Bukkit events or implements some other mechanism for gaining XP. You can create an instance of the LevelerContext
class to help you create a leveler. It contains useful methods like checking blocked locations and players. To create an instance, you need to pass an instance of the API and the SourceType
returned when you registered it.
After you register the source type, you still have to create a sources file for your skill to actually define the XP source. In this example, we create a sources/trading.yml
file:
You are responsible for generating the sources file in the user's folder using Plugin#saveResource
.
Rewards are added by creating a rewards file in the same format as the AuraSkills rewards files. For this example, create a file at rewards/trading.yml
. We make Trading give the Luck stat every skill level and the Dexterity stat created above every two levels:
To add a custom ability, use the CustomAbility.builder
static method to get an instance of CustomAbilityBuilder
. This example creates an ability called Magic Archer that gives additional Archery XP when using spectral or tipped arrows. We create a new class to hold static constant references to our abilities for easier access.
Then, register your CustomAbility
using the NamespacedRegistry
in your plugin's onEnable.
You now need to actually implement your ability's functionality. This will vary depending on the mechanics of your ability, but will typically follow this general flow:
Listen to some Bukkit event
Perform some checks confirming the ability can actually be used. You can create an instance of theAbilityContext
class and use methods like isDisabled
and failsChecks
to return early.
Get the player's ability value using Ability#getValue(SkillsUser#getAbilityLevel)
Use the value to modify gameplay mechanics
The implementation of the example ability won't be shown, but it would be done by listening to the EntityXpGainEvent
and using setAmount
to change the XP gained.
For your ability to work, it must be linked to a skill. You can do this by calling the ability
or abilities
methods on CustomSkillBuilder
when building your CustomSkill
. You can also add it to the abilities
list of a skill in any skills.yml
configuration file, including for existing default skills. Make sure to use the full NamespacedId to reference your ability in the config in the format pluginname/abilityname
.
The example above hardcoded the values for baseValue, unlock, levelUp, etc. If you want to make these values configurable by the user, create an abilities.yml
file in your content directory. The format is the same as the AuraSkills file.
You are responsible for generating abilities.yml
in your user's plugin folder using Plugin#saveResource
.
Adding a custom mana ability is similar to creating a normal ability. Use the builder to create a CustomManaAbility
instance. This example creates a mana ability called Leap for Agility that launches the player forward when right clicking a feather. We create a new class to hold a static constant reference to our mana abillity for easier access.
To define the values for your mana ability like base_value, value_per_level, base_cooldown, base_mana_cost, etc., you can either set them directly using the builder methods or create a mana_abilities.yml
file in your content directory in the same format as the AuraSkills file, but with the mana ability name being your mana ability's NamespacedId of course. You should define all the necessary options using one of the two methods, otherwise they will use arbitrary default values.
Make sure to register your CustomManaAbility
in your plugin's onEnable.
You must then implement the functionality for your mana ability yourself using Bukkit events and other API calls to get the mana ability values. For example, to get the value for a user, get the mana ability level using SkillsUser#getManaAbilityLevel
and pass it into ManaAbility#getValue
: