Mechanism System (triggers × actions)
In: Server Admin Guide Overview · Previous: Spawning & Clearing · Next: Placement Profiles
Related: Blueprint & Objectives · Mechanism Editing · config.yml Full Configuration
A Mechanism is a programmable world interaction in the blueprint: "trigger → a chain of actions." A player steps on a plate, digs through a wall, walks into a region, advances a stage, applies a redstone charge… and the actions you configured run: open a door, spawn an ambush, play a title, give a reward, teleport…
🔑 Architecture red line: a mechanism is pure world interaction and never touches attributes / damage. It can fill blocks, spawn mobs, play sounds, and dispense loot, but it won't change anyone's attack or health—that's the job of QinhItems / attribute plugins. This is of a piece with QR's overall "doesn't compute numbers" stance (see Core Concepts).
Mechanisms are written in the mechanisms section of templates/<template-id>/blueprint.yml, and can also be configured visually with /qr editor's Mechanism Editing.
🖼️ [Image placeholder] A "trigger → action chain" flow illustration (step on plate → spawn ambush + play title + play sound) · suggested
assets/mechanism-flow.png
1. What a mechanism looks like
Each mechanism is an entry in the mechanisms list:
mechanisms:
- id: open_door # Unique identifier
trigger: { type: REDSTONE, x: 4, y: 1, z: 0 } # Trigger: which kind, where
actions: # Action chain: executed in order
- { type: FILL, from: { x: 3, y: 1, z: 0 }, to: { x: 5, y: 3, z: 0 }, material: AIR }
once: false # Whether to trigger only once
cooldown: 0 # Cooldown (seconds)
require-stage: 0 # Required stage
radius: 24 # Audience / effect radius (blocks)Mechanism top-level fields
| Field | Meaning | Default | Notes |
|---|---|---|---|
id | Unique identifier of the mechanism | required | No duplicates within the same blueprint |
trigger | Trigger (see §2) | required | Contains type and the corresponding pos / region / interval / stage |
actions | Action chain (see §3) | required | A list, executed in order; a mechanism with an empty list is ignored |
once | Whether to trigger only once | false | true = this anchor triggers only once ever (persistently recorded, survives reload) |
cooldown | Trigger cooldown (seconds) | 0 | After triggering, no response for N seconds |
require-stage | Required stage | 0 | Only triggers when the current clear stage ≥ this value; 0 = unrestricted |
radius | Audience / effect radius (blocks) | 24 | Used by "find nearby players" actions like MESSAGE / TITLE / SOUND / EFFECT / TELEPORT(all) |
Caution
All coordinates are relative to the structure origin (structure minimum corner = 0,0,0), consistent with the other blueprint fields. See Blueprint & Objectives §1.
The pre-fire gates (check order before firing)
After a mechanism is hit by its trigger, it passes these checks in order before the actions actually run:
require-stage: current clear stage insufficient → skip.once: already triggered (present in the persistent record) → skip.cooldown: still on cooldown → skip.- All passed → execute
actionsin order; ifonce, record it; if there's acooldown, start the timer.
2. The 6 triggers (MechTriggerType)
trigger.type decides "what triggers this mechanism," 6 in total. Different triggers read different fields from trigger:
| Trigger type | Trigger condition | Required fields |
|---|---|---|
INTERACT | Player right-clicks the specified block | x/y/z (trigger block coordinate) |
BLOCK_BREAK | Player mines the specified block | x/y/z (trigger block coordinate) |
REDSTONE | The specified block goes from unpowered to powered (rising edge) | x/y/z (trigger block coordinate) |
REGION_ENTER | Player walks into the specified region (fires once on entry) | from + to (the two corners of the region) |
TIMER | While a player is nearby, fires every N seconds | interval (seconds) |
STAGE | Fires when clear progress advances to the specified stage | stage (stage number) |
How to write trigger fields
# Block kinds (INTERACT / BLOCK_BREAK / REDSTONE): give a single-point coordinate
trigger: { type: INTERACT, x: 4, y: 1, z: 0 }
# Region kind (REGION_ENTER): give the from / to corners
trigger:
type: REGION_ENTER
from: { x: 2, y: 1, z: 2 }
to: { x: 6, y: 3, z: 6 }
# Timer kind (TIMER): give interval (seconds)
trigger: { type: TIMER, interval: 30 }
# Stage kind (STAGE): give stage
trigger: { type: STAGE, stage: 2 }A few key behaviors
- REDSTONE only triggers on the rising edge (the moment it goes from 0 power to powered); it won't keep firing because of sustained power.
- BLOCK_BREAK's trigger block is allowed to be dug through—even when the ruin is in protection lock, this block can be broken (otherwise it couldn't trigger). See Spawning & Clearing §5.
- REGION_ENTER is "fires once on entry": standing inside the region won't repeatedly trigger; you have to walk out and back in for it to trigger again.
- TIMER requires a nearby player for its timer to advance (it doesn't idle-spin when nobody's around).
- INTERACT only recognizes a main-hand right-click on the block.
⚙️
REGION_ENTERandTIMERrely on background periodic scanning, constrained byconfig.yml'smechanisms.scan-radius(default 48, mechanisms are only evaluated when a player enters this range) andmechanisms.period-ticks(default 10, evaluation interval). Block kinds (INTERACT / BLOCK_BREAK / REDSTONE) respond instantly via events and don't consume the scan budget.
3. The 12 actions (MechActionType)
Each item's type in actions decides what it does, 12 in total. Action parameters have two writing styles:
- Structured coordinates:
pos/from/to(written as{ x:.., y:.., z:.. }), used for positional actions; - params: every remaining key besides
type/pos/from/to/x/y/zis read as a parameter (values parsed as strings).
Below, each one is explained, listing which parameters it reads.
1. FILL — fill a region with blocks
Fill an entire region with a certain block (open a door, cave-in, raise a wall, flood with water…).
| Parameter | Meaning | Default |
|---|---|---|
from / to | The two corners of the region (relative coordinates) | required |
material | Fill material (Bukkit Material name) | AIR |
# Fill the doorway with air = open the door
- { type: FILL, from: { x: 3, y: 1, z: 0 }, to: { x: 5, y: 3, z: 0 }, material: AIR }
# Raise a stone wall to block the path
- { type: FILL, from: { x: 0, y: 1, z: 5 }, to: { x: 8, y: 4, z: 5 }, material: STONE }Caution
A region whose volume exceeds config.yml's mechanisms.max-fill-volume (default 20000 blocks) is skipped outright to prevent server lag. For large-scale remodeling, split it into multiple mechanisms or raise the limit. A misspelled material name is silently skipped.
2. SPAWN — spawn mobs
Spawn mobs at a specified point (ambush, reinforcement, stage boss).
| Parameter | Meaning | Default |
|---|---|---|
pos | Spawn point (relative coordinates) | (0,0,0) |
mob | Mob key: vanilla name or mm-<MM name> | required |
level | Level (only takes effect for MM mobs) | 1 |
count | How many to spawn | 1 |
- { type: SPAWN, pos: { x: 5, y: 2, z: 8 }, mob: ZOMBIE, count: 4, level: 1 }
- { type: SPAWN, pos: { x: 6, y: 2, z: 9 }, mob: mm-FireSkeleton, count: 1, level: 5 }Tip
Mobs spawned by a SPAWN mechanism carry no clear-kill marker and don't count toward objectives stage progress. For mobs that should count toward progress, use the blueprint's spawn-points (see Blueprint & Objectives). Mechanism SPAWN suits "atmospheric ambushes."
3. MESSAGE — chat message
Send one line of chat message to players within the radius.
| Parameter | Meaning |
|---|---|
text | Message text (supports color codes) |
- { type: MESSAGE, text: "&c机关启动!小心脚下!" }Constrained by radius (sent to players near the triggerer).
4. TITLE — screen title
Display a screen title to players within the radius.
| Parameter | Meaning |
|---|---|
title | Main title |
subtitle | Subtitle (optional) |
- { type: TITLE, title: "&6封印解除", subtitle: "&7通往深处的门已开启" }5. SOUND — sound effect
Play a sound to players within the radius.
| Parameter | Meaning | Default |
|---|---|---|
sound | Sound name (Bukkit Sound name) | required |
volume | Volume | 1.0 |
pitch | Pitch | 1.0 |
- { type: SOUND, sound: BLOCK_PISTON_EXTEND, volume: 1.0, pitch: 0.8 }6. EFFECT — potion effect
Apply a potion effect to players within the radius (slowness trap, blindness, night-vision buff…).
| Parameter | Meaning | Default |
|---|---|---|
effect | Effect name (PotionEffectType name) | required |
level | Level (from 1, 1 = base level) | 1 |
seconds | Duration in seconds | 5 |
- { type: EFFECT, effect: SLOWNESS, level: 2, seconds: 8 }7. COMMAND — execute a command
Execute a command. {player} is replaced with the triggerer's name.
| Parameter | Meaning | Default |
|---|---|---|
command | Command (leading / may be omitted) | required |
as | As whom: console (console) / player (the triggering player) | console |
# Console gives the triggerer money
- { type: COMMAND, command: "eco give {player} 100", as: console }
# Execute as the player
- { type: COMMAND, command: "warp dungeon_exit", as: player }Tip
With as: player the triggering player runs the command themselves, subject to their permissions; as: console has full console permissions.
8. LOOT — dispense loot
Dispense loot to the triggerer per a loot table (dropped on the ground).
| Parameter | Meaning | Default |
|---|---|---|
table | Loot table name (loottables/<name>.yml) | required |
pos | Drop point (relative coordinates); if omitted, drops at the triggerer's feet | triggerer's position |
growth-scaled | Whether to scale quantity by growth | true |
- { type: LOOT, table: vault, pos: { x: 6, y: 1, z: 6 }, growth-scaled: true }Caution
Requires a triggerer (player) to dispense; a mechanism triggered without a player (REDSTONE / STAGE, etc.) using LOOT won't dispense because there's no recipient.
9. TELEPORT — teleport
Teleport players to a specified point.
| Parameter | Meaning | Default |
|---|---|---|
pos | Destination point (relative coordinates) | required |
yaw | Facing yaw (optional) | unchanged |
pitch | Facing pitch (optional) | unchanged |
target | Who to teleport: trigger (triggerer only) / all (everyone within the radius) | trigger |
# Teleport the triggerer to a secret room
- { type: TELEPORT, pos: { x: 2, y: 10, z: 2 }, yaw: 90, target: trigger }
# Pull the whole team into the boss room
- { type: TELEPORT, pos: { x: 10, y: 1, z: 10 }, target: all }10. PARTICLE — particles
Emit particles at a specified point for visual effect.
| Parameter | Meaning | Default |
|---|---|---|
pos | Particle center (relative coordinates) | (0,0,0) |
particle | Particle name (Bukkit Particle name) | FLAME |
count | Particle count (1–2000) | 20 |
spread | Spread radius | 0.5 |
- { type: PARTICLE, pos: { x: 6, y: 2, z: 6 }, particle: SOUL_FIRE_FLAME, count: 60, spread: 1.0 }11. GIVE — give an item
Put an item directly into the triggerer's inventory (drops at their feet if full).
| Parameter | Meaning | Default |
|---|---|---|
item | Item reference (item-source identifier such as qi-xxx, resolved by the CoreLib item bridge) | required |
amount | Quantity | 1 |
- { type: GIVE, item: qi-dungeon_key, amount: 1 }Tip
item goes through CoreLib's unified item bridge and can reference item sources like QinhItems / MMOItems / vanilla; if it can't be resolved, nothing is given. Requires a triggering player.
12. NPC — spawn an NPC
Spawn a Citizens NPC at a specified point (gatekeeper, guide, story character).
| Parameter | Meaning | Default |
|---|---|---|
pos | Spawn point (relative coordinates) | (0,0,0) |
name | NPC name | NPC |
skin | Skin (player name, optional) | unset |
yaw | Facing yaw (optional) | unset |
- { type: NPC, pos: { x: 4, y: 1, z: 4 }, name: "&e守墓人", skin: Notch, yaw: 180 }Caution
The NPC action requires Citizens installed; without it, this action has no effect.
4. config.yml — mechanisms section
The global switch and rate limiting for the mechanism system are in config.yml:
# Programmable mechanisms (in-blueprint trigger→action, pure world interaction not attributes)
mechanisms:
enabled: true # Master switch (off = no mechanisms respond server-wide)
scan-radius: 48 # Region/timer trigger scan radius (mechanisms evaluated only when a player enters this range)
period-ticks: 10 # Region/timer trigger evaluation interval in ticks (larger = cheaper, slower region-entry response, floor 2)
max-fill-volume: 20000 # Max blocks per FILL action (prevents oversized-region lag)| Config | Meaning | Default |
|---|---|---|
mechanisms.enabled | Mechanism system master switch | true |
mechanisms.scan-radius | Scan radius for REGION_ENTER / TIMER | 48 |
mechanisms.period-ticks | Evaluation interval in ticks for REGION_ENTER / TIMER | 10 |
mechanisms.max-fill-volume | Max blocks per FILL (excess skipped) | 20000 |
5. Complete example set
Example 1: pressure-plate door (region entry → open door + prompt)
The player walks into the area in front of the door; the doorway is automatically filled with air, with a sound and a prompt:
mechanisms:
- id: auto_door
trigger:
type: REGION_ENTER
from: { x: 3, y: 1, z: 7 }
to: { x: 5, y: 2, z: 8 }
actions:
- { type: FILL, from: { x: 3, y: 1, z: 9 }, to: { x: 5, y: 3, z: 9 }, material: AIR }
- { type: SOUND, sound: BLOCK_IRON_DOOR_OPEN, volume: 1.0, pitch: 1.0 }
- { type: MESSAGE, text: "&7一道暗门在你面前缓缓开启……" }
cooldown: 3
radius: 16Example 2: dig through a hidden wall to spawn an ambush (break block → spawn + title)
The player mines the marker block hidden in the wall, triggering the ambush:
mechanisms:
- id: ambush
trigger: { type: BLOCK_BREAK, x: 6, y: 2, z: 4 }
actions:
- { type: TITLE, title: "&c埋伏!", subtitle: "&7你触发了陷阱" }
- { type: SOUND, sound: ENTITY_ZOMBIE_AMBIENT, volume: 1.0, pitch: 0.7 }
- { type: SPAWN, pos: { x: 6, y: 2, z: 5 }, mob: ZOMBIE, count: 4, level: 1 }
- { type: SPAWN, pos: { x: 7, y: 2, z: 5 }, mob: mm-FireSkeleton, count: 1, level: 3 }
once: true # This wall ambushes only once
require-stage: 1 # Only triggers after stage oneExample 3: stage-completion teleport + reward (stage advance → teleport whole team into boss room + dispense reward)
When clear progress advances to stage 2, pull everyone nearby into the secret chamber and dispense loot:
mechanisms:
- id: stage2_gate
trigger: { type: STAGE, stage: 2 }
actions:
- { type: TITLE, title: "&6前哨已肃清", subtitle: "&7深处的守卫苏醒了" }
- { type: TELEPORT, pos: { x: 10, y: 1, z: 10 }, yaw: 0, target: all }
- { type: LOOT, table: vault, pos: { x: 10, y: 1, z: 12 }, growth-scaled: true }
once: true
radius: 32Example 4: timed mechanism (timer → periodic particles + slowness)
While a player is nearby, emit poison-mist particles and apply slowness every 20 seconds, creating a dangerous room:
mechanisms:
- id: poison_room
trigger: { type: TIMER, interval: 20 }
actions:
- { type: PARTICLE, pos: { x: 6, y: 2, z: 6 }, particle: SNEEZE, count: 80, spread: 3.0 }
- { type: EFFECT, effect: SLOWNESS, level: 1, seconds: 6 }
- { type: SOUND, sound: ENTITY_GENERIC_DRINK, volume: 0.6, pitch: 0.5 }
radius: 8Example 5: redstone-linked door (redstone charge → open door)
The classic mechanism: a lever / pressure plate powers a block, and the mechanism fills the door with air:
mechanisms:
- id: lever_door
trigger: { type: REDSTONE, x: 4, y: 1, z: 0 }
actions:
- { type: FILL, from: { x: 3, y: 1, z: 0 }, to: { x: 5, y: 3, z: 0 }, material: AIR }
once: false # Can be opened repeatedly
cooldown: 0Example 6: right-click altar for a reward (interact → give item + command reward + effect)
The player right-clicks the altar block to dispense a key, give money, and show an effect; each person can claim only once (using once together with… here we use a command to limit it, since the mechanism once is once per anchor):
mechanisms:
- id: altar_reward
trigger: { type: INTERACT, x: 6, y: 1, z: 6 }
actions:
- { type: PARTICLE, pos: { x: 6, y: 2, z: 6 }, particle: HAPPY_VILLAGER, count: 40, spread: 0.8 }
- { type: SOUND, sound: UI_TOAST_CHALLENGE_COMPLETE, volume: 1.0, pitch: 1.0 }
- { type: GIVE, item: qi-ancient_relic, amount: 1 }
- { type: COMMAND, command: "eco give {player} 200", as: console }
- { type: MESSAGE, text: "&a你获得了祭坛的恩赐!" }
require-stage: 2 # Only claimable after clearing
cooldown: 16. Troubleshooting cheat sheet
| Symptom | Possible cause |
|---|---|
| Mechanism does nothing at all | mechanisms.enabled: false; or actions is empty and ignored; or require-stage not reached |
| REGION_ENTER / TIMER not triggering | Player not within scan-radius; or period-ticks too large so its turn hasn't come |
| FILL has no effect | Region volume exceeds max-fill-volume; or material name misspelled |
| LOOT / GIVE dispenses nothing | The mechanism is triggered by a playerless trigger (REDSTONE / STAGE / TIMER), so there's no recipient; or the table name / item reference can't be resolved |
| NPC doesn't appear | Citizens not installed |
| Trigger block won't break | It's an INTERACT / REDSTONE trigger block (protected); only BLOCK_BREAK trigger blocks are allowed to be mined |
| Mechanism triggered once and never responds again | once: true; the record is persisted and won't reset even on reload (/qr remove that anchor to clear it) |
Next steps
- Configure mechanisms with the visual interface → Mechanism Editing
- The mechanism coordinate system / other blueprint fields → Blueprint & Objectives
- Protection and trigger-block exceptions → Spawning & Clearing §5
- How to write loot tables → Loot System