Skip to main content

Magic Actions

MagicActions owns result-aware spell writes. Use the magic and rune-pouch SDK facades for spellbook, rune, pouch, autocast, and teleport reads; see SDK Examples And Best Practices.

Select And Deselect

MethodBehavior
selectSpell(Spell)Selects the visible spell widget.
deselect()Clears the selected spell through the client API.
InteractionResult result = MagicActions.selectSpell(Spell.HIGH_LEVEL_ALCHEMY);
if (result.getStatus() == InteractionStatus.PACED) {
return; // retry next tick
}

selectSpell(null) returns TARGET_NULL. A missing spell widget returns SPELL_WIDGET_NOT_FOUND; a hidden spell widget returns SPELL_NOT_CASTABLE.

Cast On A Target

MethodTarget
cast(Spell)An untargeted spell.
castOnInventoryItem(Spell, Widget)A resolved inventory item widget.
cast(Spell, NPC)A resolved NPC.
cast(Spell, Player)A resolved player.
cast(Spell, TileObject)A resolved scene object.
cast(Spell, ETileItem)A resolved ground item.
Optional<Widget> item = Inventory.search().withId(ItemID.YEW_LONGBOW).first();
if (item.isPresent()) {
InteractionResult cast = MagicActions.castOnInventoryItem(
Spell.HIGH_LEVEL_ALCHEMY,
item.get()
);
}

Targeted casting validates the spell widget and target, then queues the spell-widget-on-target packet directly. Treat PACED as a yield and retry from a later tick. Do not queue a second click in the same tick.

For workflows that combine rune checks, inventory selection, retries, and production state, keep policy in the caller or a workflow builder rather than adding it to MagicActions.

Live Verification

Spell widgets and selected-spell metadata are revision-sensitive. After a RuneLite revision change, verify the spell is visible, the selection metadata matches the requested spell, the target click lands once, and the expected inventory or ground-item change occurs. Unit tests cover failure statuses and packet routing but do not prove the live widget contract.