Skip to content

Action Handler Reference

Belongs to: Action System · Related: Triggers · Action Handler Development

A handler is the "effect" that actually executes after a trigger fires. It is referenced in the refs list using handler + payload. This page lists all built-in handlers and their payload formats.

🔎 Want per-field details + multiple writing variants + common pitfalls for each handler? See Action Handler Details.

Syntax recap:

yaml
refs:
  - handler: qi:message
    payload: "Hello {player}"
  - handler: qi:sound
    payload: "minecraft:entity.player.levelup;1;1.0"

Multiple refs execute in order.


QI Core Handlers (10 built-in)

Handler IDpayload formatBehavior
qi:messageplain text (MiniMessage / & color codes)Sends a chat message to the player
qi:action_barplain text (MiniMessage)Action bar text above the hotbar, e.g. <gold>◎ Ready!</gold>
qi:titlemain title||subtitle||fade-in||stay||fade-out (fields after the first can be omitted)On-screen title; time units × 50ms
qi:subtitleplain text (MiniMessage)Subtitle only (empty main title)
qi:soundnamespace:sound_key;volume;pitchPlays a sound, e.g. minecraft:entity.player.attack.strong;1;0.8
qi:bossbartext;progress(0-1);color;style;duration in ticksBoss health bar; colors PINK/BLUE/RED/GREEN/YELLOW/PURPLE/WHITE; styles PROGRESS/6/10/12/20
qi:commandcommand text (without /, supports {player})Executes a command as the player
qi:console_commandcommand text (without /, supports {player})Executes a command as the console
qi:give_itemitem source reference (e.g. my_sword_id or ce-wooden_axe)Gives an item to the player
qi:close_inventory(empty)Closes the container the player has open

Detailed payload examples

qi:title — fields separated by ||:

yaml
- handler: qi:title
  payload: "<gold>⚡ Thunder ⚡</gold>||<gray>The roar echoes</gray>||3||30||10"
  #          main title              subtitle                 fade-in stay fade-out (×50ms)

qi:sound — separated by ;:

yaml
- handler: qi:sound
  payload: "minecraft:entity.lightning_bolt.thunder;1;1.2"
  #          sound key                               volume pitch

qi:bossbar:

yaml
- handler: qi:bossbar
  payload: "<red>Charging</red>;0.5;RED;PROGRESS;40"
  #          text             progress color style    duration in ticks

qi:command / qi:console_command{player} is replaced with the player's name:

yaml
- handler: qi:command
  payload: "effect give {player} minecraft:strength 10 1"
- handler: qi:console_command
  payload: "say {player} triggered a skill"

Demo Handlers

Handler IDpayloadBehavior
qi:echoplain textEchoes to chat (demo only)
demo:noopJSON (optional note)Does nothing (demo only)

Ecosystem Handlers (registered by other plugins)

Handler IDSourcepayload format
qinhskills:castQinhSkills bridgeJSON: {"skill":"skillID","level":1} — casts a QS skill
combat:swingCombat modulelight or heavy — performs an attack action
ap:triggerAttributePlusOpaque, handled internally by AP

qinhskills:cast — hands skill casting over to QinhSkills:

yaml
- handler: qinhskills:cast
  payload: '{"skill":"fireball","level":1}'

combat:swing — a swing that works with the Attribute System:

yaml
- handler: combat:swing
  payload: "light"      # or "heavy"

payload Serialization Modes

A handler's payload has two modes (determined by its payload schema):

  • PLAIN: single field, the payload is a bare string (e.g. Hello for qi:message).
  • JSON: multiple fields, the payload is a JSON object (e.g. {"skill":"...","level":1} for qinhskills:cast).

The GUI editor automatically generates a form based on the schema (Action Editor).


Developing Custom Handlers

Need an effect beyond the built-in handlers? Implement the QinhActionHandler interface and register it. This is the only proper way to bring complex logic (if/switch/state) into the action system (you cannot write logic in YAML). See Action Handler Development for details.

kotlin
QinhItemsAPI.actions().registerHandler(object : QinhActionHandler {
    override val handlerId = "myplugin:my_handler"
    override fun dispatch(ctx: QinhActionContext): ActionDispatchResult {
        ctx.player.sendMessage("Executing: ${ctx.payload}")
        return ActionDispatchResult.HANDLED
    }
})

Next Steps