Passive Skills (passive)
Previous: Triggers · Next: Targeting and Target Selection
A passive skill = a skill that the player doesn't press a key for; it triggers automatically when a condition is met. Thorns on taking damage, lifesteal on kill, berserk at low health, a buff stack lost every second…—all powered by passives.
💡 Division of labor in one sentence: QS decides "when it triggers," MythicMobs decides "what gets cast when it does." A passive also requires a same-named skill on the MM side to have real effects, otherwise it only sends a placeholder message.
🖼️ [Image placeholder] A diagram of "player takes a hit → ON_DAMAGED event → QS triggers retaliate → MM reflects damage to the attacker" · suggested
assets/passive-retaliate.png
1. How to write a passive skill (overview)
A passive only adds three things over an active, and drops one:
- Adds: top-level
type: passiveandmeta.type: passive(both required). - Adds: a
passive_triggerslist, listing "what event triggers it." - Adds: a
cooldown_msrate limit for high-frequency events. - Drops:
trigger.primarycan be omitted—since 1.0.16 the schema auto-handles it asPASSIVE(writing it works too, omitting it is simpler).
type: passive # ★ this single line is what actually makes it passive
meta:
type: passive # also write passive in meta
passive_triggers: # passive trigger list (multiple allowed; hitting any one triggers it)
- type: ON_ATTACK # when an attack lands
id: retaliate
cooldown_ms: 0 # rate limit: 0 = no limit; high-frequency events must use a non-zero value
- type: ON_LOW_HEALTH # when health drops below the threshold
id: last_stand
threshold_pct: 30 # health percentage threshold (0-100), default 30, per-skillEach passive_triggers entry has three parts:
| Field | Required | Meaning |
|---|---|---|
type | ✅ | trigger type (one of the 11 in the table below) |
id | ✅ | identifier for this trigger (used to distinguish multiple triggers) |
cooldown_ms | optional | rate limit: this trigger fires at most once within these milliseconds (default 0 = no limit) |
threshold_pct | optional | ON_LOW_HEALTH only: health percentage threshold, default 30 |
⚙ Passives don't auto-unlock by default. Before testing, run
/qs unlock <skill>first, then go trigger the condition to test the effect.
2. The 11 passive trigger types
Driven by PassiveTriggerListener. Grouped by purpose into three categories:
Combat
| type | Driving event | Meaning | Target passed to MM | Needs rate limit |
|---|---|---|---|---|
ON_DAMAGED | EntityDamageEvent | when taking damage | — | ⚠️ strongly recommended |
ON_ATTACK | player as damager | when an attack lands | the victim is passed as @Target / @Trigger | depends on frequency |
ON_KILL | EntityDeathEvent | when killing a creature | the dead entity is the target | usually not needed |
ON_LOW_HEALTH | health edge | triggers once when health drops below the threshold | — | edge-trigger has built-in anti-spam |
Behavior
| type | Trigger moment | Meaning | Needs rate limit |
|---|---|---|---|
ON_SNEAK | start sneaking | when sneaking | ⚠️ strongly recommended |
ON_JUMP | jumping | when jumping (high frequency) | ⚠️ required |
ON_SPRINT | start sprinting | when sprinting | recommended |
ON_BLOCK_BREAK | breaking a block | when mining (high frequency) | ⚠️ required |
ON_RESPAWN | respawn | after dying and respawning | not needed |
ON_FALL | FALL damage | when taking fall damage | depends |
Periodic
| type | Driven by | Meaning | Needs rate limit |
|---|---|---|---|
TICK | passive.tick_interval_ticks (config.yml, default 20 ticks = 1 second) | triggers once every fixed interval | ⚠️ spams extremely easily, must be rate-limited via skill cooldown or cooldown_ms |
💡 TICK has no idle overhead: when no skill uses a
TICKpassive, the periodic task idles automatically and incurs no extra performance cost. It only works when there's actually a TICK passive.
3. The edge semantics of ON_LOW_HEALTH (clarified in detail)
Many people think "low-health trigger" = it fires continuously as long as health is low—it doesn't. ON_LOW_HEALTH is an edge trigger, tracking state with lowHealthLatch:
Rule: when
health percentage ≤ threshold_pct(source uses<=, so exactly equal counts too) and the skill is not yet latched, it triggers once and records the latch; after that it won't trigger again even if you keep taking damage; only when health recovers to> threshold(strictly above the threshold) is the latch released, and it triggers again next time you drop below.
⚙ Edge/latch details: the player gets a low-health check scheduled both on taking damage and on healing—not only on taking damage. Taking damage that pushes health to
≤ thresholdtriggers and locks; healing that pulls health back to> thresholdunlocks (but healing itself doesn't trigger). Thanks to this latch, dropping below once per life casts only once—it won't spam every time you take damage.
In one sentence: health ≤ threshold% (including exactly equal) triggers once; recovery strictly above the threshold resets it.
passive_triggers:
- type: ON_LOW_HEALTH
id: last_stand
threshold_pct: 30 # triggers when health ≤ 30% (per-skill setting, 0-100)An example (threshold 30%):
| Moment | Health change | Triggers? | Note |
|---|---|---|---|
| ① | 100% → 35% | ❌ | hasn't dropped below 30% yet |
| ② | 35% → 25% | ✅ triggers once | the moment it crosses the threshold |
| ③ | 25% → 10% | ❌ | already below the threshold, no repeat trigger |
| ④ | 10% → 50% | ❌ | healed above the threshold, latch resets (but healing itself doesn't trigger) |
| ⑤ | 50% → 20% | ✅ triggers again | drops below again after reset |
This is exactly the semantics you want for "near-death berserk / panic ultimate"—dropping below once per life casts only once, and won't spam wildly when taking a combo.
4. High-frequency passives = must rate-limit (must read)
The following triggers fire extremely often; without a rate limit they'll spam in quick succession (message flood, MM skills firing repeatedly):
⚠️
ON_DAMAGED/ON_JUMP/ON_BLOCK_BREAK/ON_SNEAKmust be rate-limited withcooldown_ms. Same forTICK—hold the frequency down with the skill'scooldownorcooldown_ms.
passive_triggers:
- type: ON_BLOCK_BREAK
id: mining_buff
cooldown_ms: 3000 # ★ triggers at most once per 3 seconds, otherwise mining a patch of stone spams itTwo rate-limiting methods (stackable):
- Per-trigger
cooldown_ms: precise to "this one trigger," recommended. - Skill-level
cooldown.base: the whole skill's cooldown, applies to all triggers.
⚙ Settlement timing: high-frequency passive events (
ON_DAMAGED/ON_ATTACK/ON_KILL/ON_BLOCK_BREAK, etc.) are all uniformly settled by QS after the MONITOR phase (avoiding events that other plugins cancel)—admins don't need to worry about this part. The only thing you need to do is set acooldown_msrate limit on these high-frequency passives.
5. TICK periodic configuration
The TICK interval is controlled centrally in config.yml; all TICK passives share this beat:
# config.yml
passive:
tick_interval_ticks: 20 # TICK passive trigger interval (ticks, 20 = 1 second)
# when no TICK passive skill exists, the task idles with no overhead# in the skill: a periodic passive triggering once per second (following the beat above)
type: passive
meta: { type: passive }
passive_triggers:
- type: TICK
id: regen_aura
cooldown_ms: 1000 # even with a 1-second beat, adding cooldown_ms is recommended as a safety net6. Reproduction: retaliate.yml (the standard passive skill example)
This is QS's bundled passive example skills/combat/retaliate.yml—copy it as is:
#==============================================================================
# Thorns Retaliation retaliate —— passive skill: automatically counterattacks when attacked
#==============================================================================
id: retaliate
display: "&c荆棘反击"
meta:
category: combat
type: passive # passive: both type fields must say passive
state:
required: IDLE
graph:
entry: retaliate
execution:
mythic_skill: retaliate
# a passive skill can omit trigger.primary —— the schema auto-handles it as PASSIVE
type: passive # ★ this single line is what actually makes it passive
max_level: 1
cooldown:
base: 0 # skill-level cooldown; for passive rate-limiting, each trigger's own cooldown_ms is preferred
# passive trigger list: write multiple; hitting any one triggers this skill
passive_triggers:
- type: ON_DAMAGED # when taking damage
id: thorns
cooldown_ms: 1500 # ★ rate limit: at most once per 1.5 seconds, to avoid retaliation spam during a comboNote: this example uses
ON_DAMAGED. If you want the "attacker" to be the one retaliated against, switch toON_ATTACKand pass the attacker as@Triggerto MM (see the next section).
7. How the MM side receives a passive (@Trigger / @Target)
A passive is only the "trigger"; the real effect goes in a same-named MythicMobs skill. The key is how to get the "trigger target":
ON_ATTACK: the victim is passed as@Target/@Trigger.ON_KILL: the dead entity is passed as the target.- To make the attacker take the retaliation: use
ON_ATTACKand settle damage on@Triggerin MM.
# the same-named skill retaliate under plugins/MythicMobs/skills/
retaliate:
Skills:
- damage{amount=4} @Trigger # deal damage to the trigger target (the attacker)
- particles{p=crit;amount=20} @TriggerOne iron rule runs through the ecosystem: QS does not bake in damage values. The
damage{}value is ultimately settled on the MM side by attribute plugins like AttributePlus.
8. Common passive pitfalls
| Symptom | Cause | Fix |
|---|---|---|
| Passive doesn't trigger at all | not unlocked | /qs unlock <skill> |
| Passive only sends a placeholder message, no effect | no same-named skill in MM | add the retaliate skill on the MM side |
| Wild spam when jumping / mining | high-frequency trigger not rate-limited | add cooldown_ms to that trigger |
| Low-health skill fires every time you take damage | mistaken for a threshold trigger | it's an edge trigger, this is expected; adjust threshold_pct to change frequency |
type written in only one place | both meta and top-level must say passive | add type: passive in both places |
@Trigger in MM can't get the attacker | used ON_DAMAGED | switch to ON_ATTACK |
Further reading
- Next: Targeting and Target Selection — how active skills lock targets (a passive's target is given by the trigger event).
- Triggers — the relationship between
PASSIVEand other TriggerTypes. - Cooldowns, Charges, GCD, and Conflicts — details of the
cooldownfields. - Connecting MythicMobs — same-named skills and variable reception on the MM side.