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
| Method | Behavior |
|---|---|
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
| Method | Target |
|---|---|
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.