Skip to content

Skills and the menu ​

Skills are the abilities a magic item offers. Rimulib shows them in a shared menu that players open with H. Your mod decides when a skill is cast.

Define skills ​

An enum works well. Implement Skill:

java
public enum MySkill implements Skill {
    METEOR;

    public String id() { return "meteor"; }
    public String tier() { return "Skill"; }
    public String title() { return "Meteor"; }
    public int color() { return 0xFF7FB0FF; }
    public int cooldown() { return 200; }
    public int duration() { return 60; }
    public int defaultKey() { return 0; }
}

Register the set ​

Do this in your common init, so the set exists before Rimulib's client setup runs.

java
public static final SkillSet SET = SkillApi.register("mymod", "staff", 0x7FB0FF,
    MySkill.values(), (player, skill, tuning) -> {
        // Run the skill here and return true if it was cast
        return true;
    });

Use registerHidden for a set that should stay out of the menu.

Your item implements SkillHolder:

java
public class StaffItem extends Item implements SkillHolder {
    public SkillSet skillSet() { return MyMod.SET; }
}

SkillApi.held(player) returns the holder in the player's hands, and SkillApi.holds(player, set) checks for one set.

Cast a skill ​

Rimulib does not cast for you. Send your own packet from the client, then cast on the server:

java
SET.cast(player, skill, SkillApi.tuning(skill));

tuning gives the default slider values for that skill.

Assets ​

WhatWhere
Card art, 64 by 32assets/mymod/textures/gui/sprites/skill/staff/meteor.png
DescriptionLanguage key skill.mymod.staff.meteor.desc
Key nameLanguage key key.mymod.staff.meteor

Add your mod to the menu ​

From your client init:

java
MenuApi.source("mymod")
    .order(5)
    .credit("Made by", "@yourname");

Higher order values are listed first. credit shows your notice in the menu, with the handle in red.

MethodWhat it does
MenuApi.open()Opens the menu
MenuApi.isOpen()Whether the menu is open
MenuApi.ownScreen(set, open)Opens your own screen for that set's items
MenuApi.lock(set, skills...)Adds greyed-out rows for skills that are not available yet
MenuApi.capturesInput()Whether the menu is taking the keyboard
MenuApi.binding()The skill waiting for a new key, or null
MenuApi.onKey(hook)Sees keys first. Return true to use the key
MenuApi.key(skill)The key bound to a skill
MenuApi.menuKey(), filmKey()The shared menu and film keys
UiApi.onMenuDraw(draw)Draws your own panel over the menu

Add to another mod's set ​

You can put your skills on a set that belongs to another mod. They appear with its skills. If that mod casts through its set, your skills also go through its cast checks and cooldowns.

Use whenRegistered so load order doesn't matter. Run it on both client and server, in your common init, so skill numbers stay the same on both sides.

java
SkillApi.whenRegistered("othermod", set -> {
    if (set.id.getPath().equals("staff")) {
        SkillApi.extend(set, MySkill.values(), MyMod::cast);
    }
});

Check casts first ​

A gate sees every cast of a set before it runs. Return the tuning to use, or null to refuse the cast.

java
SkillApi.gate(set, (player, skill, tuning) -> {
    if (!allowed(player)) {
        SkillApi.deny(player, Component.literal("Not here"));
        return null;
    }
    return SkillApi.clamp(tuning, skill, MY_LIMITS);
});

deny shows a line above the hotbar. limit and limits set and read a skill's slider limits.

Cooldowns and shared films ​

Mods keep their own cooldowns. A mod can share them through Rimulib so other mods can read them:

java
SkillApi.shareCastState("mymod", new CastState.Source() {
    public int remaining(ServerPlayer player, Skill skill) { return ticksLeft(player, skill); }
    public void clearCooldowns(ServerPlayer player) { reset(player); }
    public boolean filmsForAll(ServerPlayer player) { return sharesFilms(player); }
});
MethodWhat it does
cooldown(player, skill)Ticks until the skill is ready
clearCooldowns(player, modId)Resets that player's cooldowns for a mod
filmsForAll(player, modId)Whether the player shares films with everyone nearby

If a mod shares nothing, cooldown returns 0, filmsForAll returns false and clearCooldowns does nothing. The Shooting Star demo shares its cast state from the next demo build, so older demo versions read as nothing recharging.

Look up skills ​

MethodReturns
setOf(skill)The set a skill belongs to
index(skill)The skill's network number within its mod
byIndex(modId, index)The skill with that number
count(modId)How many skills a mod has
sets(modId)A mod's skill sets

Force kill ​

SkillApi.forceKill("mymod", true) lets the damage slider reach its erasing step. Set it in your common init, before any strike runs.

forceKill(modId) and maxDamage(modId) read a mod's current settings.