Skip to main content
1

Add Skills as a dependency

Add the Skills plugin jar to your project as a compileOnly dependency. Because the jar is not published to a public Maven repository, reference it from your local files or a file-system repository.
build.gradle.kts
dependencies {
    compileOnly(files("libs/skills-0.4.13-all.jar"))
    // or via a local Maven repo:
    // compileOnly("com.hacklab.minecraft:skills:0.4.13")
}
Then declare the dependency relationship in your plugin.yml. Use depend if your plugin cannot function without Skills, or softdepend if Skills is optional.
plugin.yml (hard dependency)
name: MyPlugin
version: "1.0.0"
main: com.example.myplugin.MyPlugin
depend:
  - Skills
plugin.yml (soft dependency)
name: MyPlugin
version: "1.0.0"
main: com.example.myplugin.MyPlugin
softdepend:
  - Skills
2

Obtain the API instance

The API is registered with Bukkit’s ServicesManager. Retrieve it once during onEnable.
val registration = Bukkit.getServicesManager().getRegistration(SkillsAPI::class.java)
val api = registration?.provider
registration is null if Skills is not loaded. provider returns the live SkillsAPI implementation.
3

Handle soft dependency

If Skills is optional, guard every usage with a null check.
val api: SkillsAPI? = Bukkit.getServicesManager()
    .getRegistration(SkillsAPI::class.java)?.provider

if (api == null) {
    logger.info("Skills plugin not found — skill features disabled")
    return
}
If Skills is declared as softdepend and is not installed, api will be null. Calling any method on a null reference will throw a NullPointerException. Always check before use.
4

Query player data

With a valid api reference you can read and modify skill data for any online player.Check a player’s skill value
val swordSkill: Double = api.getSkill(player, "Swordsmanship") ?: 0.0
Check if a player meets a minimum skill requirement
if (api.hasSkillLevel(player, "Mining", 50.0)) {
    player.sendMessage("You are skilled enough to use this ore vein.")
}
Prefer hasSkillLevel() over getSkill() for threshold checks. It handles the null case internally and returns false when the skill name is invalid.
Get all skill values at once
val skills: Map<String, Double> = api.getAllSkills(player)
skills.forEach { (name, value) ->
    println("$name: $value")
}
Read stats (STR / DEX / INT)
val str: Int = api.getStat(player, "STR") ?: 0
val dex: Int = api.getStat(player, "DEX") ?: 0
val int: Int = api.getStat(player, "INT") ?: 0
Read HP, Mana, and Stamina
val currentHp  = api.getCurrentHp(player)
val maxHp      = api.getMaxHp(player)
val currentMana = api.getCurrentMana(player)
val maxMana    = api.getMaxMana(player)
val stamina    = api.getCurrentStamina(player)
val maxStamina = api.getMaxStamina(player)

Skill name formats

All methods that accept a skillName: String parameter are case-insensitive and treat spaces and underscores as interchangeable.
FormatExample
Display name (title case)"Swordsmanship", "Mace Fighting"
Enum name (upper snake case)"SWORDSMANSHIP", "MACE_FIGHTING"
Lower case with spaces"mace fighting"
Lower case with underscores"mace_fighting"
All four of the examples below refer to the same skill:
api.getSkill(player, "Mace Fighting")
api.getSkill(player, "MACE_FIGHTING")
api.getSkill(player, "mace fighting")
api.getSkill(player, "mace_fighting")
For a complete list of available skill names see the skill name reference table.

Build docs developers (and LLMs) love