Action System Overview
Belongs to: Server Owner Guide → Action System · Subpages: Triggers · Handlers · Cooldown/Cost/Condition
The action system is the "active effect / skill" engine for QI items: the player does something (trigger) → executes a chain of effects (handlers). This page covers the overall structure and YAML syntax; details are split into subpages.
1. What an action looks like
my_item:
actions:
triggers:
left_click: # trigger name (custom)
trigger:
atom: left_click # trigger atom, see Triggers
cooldown: 3s # cooldown, see Cooldown/Cost/Condition
consume: # resource cost
- "item:minecraft-redstone:1"
conditions: # trigger conditions (all must pass to execute)
- "player_level:>=10"
refs: # handler references executed in order
- handler: qi:title
payload: "<gold>Spark</gold>||<gray>Blade Resonance</gray>||3||30||10"
- handler: qi:sound
payload: "minecraft:entity.player.attack.crit;1;1.2"Structure hierarchy:
actions:
triggers:
<trigger name>:
trigger: { atom: ... } or trigger: { sequence: [...] , window: ms }
cooldown: <duration> (optional)
consume: [ <cost>, ... ] (optional)
conditions: [ <condition>, ... ] (optional)
refs:
- handler: <handler ID>
payload: <payload>
- ...2. Execution flow
player action (e.g. left click)
→ trigger atom left_click matches
→ evaluate all conditions (must all be true)
→ check cooldown (stop if on cooldown)
→ pre-trigger event QinhActionTriggerEvent (cancellable by plugins)
→ check consume (stop if resources are insufficient)
→ execute each ref's handler in order (passing payload)
each handler returns HANDLED / NOT_HANDLED / HANDLER_UNAVAILABLE
post-dispatch event QinhActionDispatchedEvent (for listening)
→ if any handler returns HANDLED:
deduct consume, record cooldownFor event details, see Events.
3. Key design: no logic in YAML
QI deliberately forbids writing flow control in action YAML: if / else / when / unless / switch / filter / rules / flow, etc., are all forbidden fields (ActionRoutingPolicy). Under a trigger, it is simply "run a chain of handlers in order"; handlers do not depend on each other's results.
What if you need complex logic? Have a developer implement an action handler, writing the if/switch/state checks into Kotlin/Java, while the YAML only references it and passes a payload.
This boundary keeps the configuration simple and fully editable by a GUI. When action-routing.strict: true in config.yml, violations raise an error; when false, they only produce a warning.
4. Where actions are loaded from
| Source | Description |
|---|---|
| Embedded (recommended) | Written directly in the item YAML's actions.triggers section |
| Standalone file | The actions_file field points to a separate file (deprecated, embedding recommended) |
⚠️ Actions are only loaded on /qi reload. After changing the YAML, you must reload, otherwise it won't take effect. Reloading resets all cooldowns and combo states.
5. Triggers and handlers at a glance
- Trigger: 100+ atoms. Click-type (left/right/shift), sneak (single click / double click / sequence), movement (sprint / glide / jump), combat (hit / take damage / kill / crit), container / crafting, entity interaction, environment, server events,
tickperiodic. For the full list, see Triggers. - Handler: 10 built-in (
qi:message/qi:action_bar/qi:title/qi:subtitle/qi:sound/qi:bossbar/qi:command/qi:console_command/qi:give_item/qi:close_inventory) + ecosystem (qinhskills:cast/combat:swing). For each one's payload format, see Handlers.
6. A complete multi-action item
legendary_sword:
type: weapon
material: diamond_sword
display_name: "<gold>Legendary Blade</gold>"
actions:
triggers:
# single atom + condition
left_click:
trigger:
atom: left_click
cooldown: 1s
conditions:
- "player_level:>=15"
refs:
- handler: qi:action_bar
payload: "<gold>▶ Slash</gold>"
- handler: combat:swing
payload: "light"
# sequence combo (sneak → left click → left click)
whirlwind:
trigger:
sequence:
- sneak_down
- left_click
- left_click
window: 400 # inter-step window (milliseconds)
cooldown: 5s
consume:
- "level:2"
refs:
- handler: qi:message
payload: "<gold>Whirlwind Slash!</gold>"
- handler: qinhskills:cast
payload: '{"skill":"whirlwind_slash","level":1}'
# on-hit trigger
on_hit:
trigger:
atom: on_hit
cooldown: 3s
consume:
- "item:redstone:1"
conditions:
- "player_sneaking:true"
refs:
- handler: qi:title
payload: "<red>Counter!</red>||<dark_red>+10 Defense</dark_red>||5||20||5"
- handler: combat:swing
payload: "heavy"🖼️ [Image placeholder] In-game scene at the moment an action triggers (title + sound + particles) · suggested
assets/action-trigger.png
7. Diagnosing actions
| Command | Purpose |
|---|---|
/qi trigger report | Show the ActionTable trigger configuration report |
/qi trigger test [itemId] [player] | Manually execute the first trigger binding of a given item |
/qi status / /qi diagnose | View action table loading status and issues |
See Commands.
Subpage navigation
- Complete Trigger Atom Reference —— all 100+ trigger atoms listed one by one
- Complete Action Handler Reference —— payload format for each handler
- Cooldown / Cost / Condition / Combo —— syntax details
- Develop custom handlers → Action Handler Development