Affix System (affixes.yml)
In: Server Owner Guide Overview · Upstream: Realm & Keystone · Related: Loot System · Affix Scripts (JS)
An Affix is a realm's enhancement modifier: a number of them are randomly injected by tier on activation, rewriting this realm's spawns / environment / rules / loot. This page breaks down every field of affixes.yml, the 11 effect.types, the danger-budget constraint, and lists the 13 built-in affixes.
🔑 Architectural red line: QR does not compute stats / attributes. The way an affix makes "mobs stronger" = attaching a level to the mob when it spawns, and MythicMobs scales the stats itself; player attributes are delegated to the attribute plugin; QR only orchestrates quantity / environment / rules / loot.
1. What an Affix Looks Like
File: plugins/QinhRuins/affixes.yml; under the top-level affixes:, each key is an affix id.
affixes:
elite-swarm: # affix id (rolled by tier on activation)
name: "&cElite Swarm" # display name (& color codes; goes into Bossbar / keystone Lore / activation broadcast)
lore: ["&7Spawn count +50%"] # description lines (the player-visible affix description)
category: MOB # category: MOB | PLAYER | ENV | LOOT (a semantic tag only, for grouping)
group: mob-count # exclusion group: only one affix in the same group appears at a time (omit = no exclusion)
danger: 30 # danger value (consumes the difficulty budget)
reward: 30 # reward value (together with danger, decides the weighted draw chance)
min-tier: 2 # minimum tier threshold (won't be rolled below this tier)
# max-tier: 999 # maximum tier threshold (optional, default 999)
effect:
type: mob-count-mult # effect type (see §2, 11 in total)
params: { mult: 1.5 } # parameters for that typeField Quick Reference
| Field | Meaning | Default |
|---|---|---|
name | Display name (& color codes); falls back to id | id |
lore | Player-visible description lines (list) | empty |
category | MOB/PLAYER/ENV/LOOT, a semantic tag | MOB |
group | Same-group exclusion group name; omit = doesn't participate in exclusion | none |
danger | Danger value, constrained by the tier's danger-budget | 10 |
reward | Reward value; danger+reward decides the weighted weight | 10 |
min-tier / max-tier | The tier range in which it appears | 1 / 999 |
effect.type | Effect type (one of 11) | empty (no effect) |
Draw weight =
danger + reward: an affix that's both dangerous and fat is more likely to be drawn. A pure-fat affix withdanger:0(Greed / Golden Touch / Hidden Trove) doesn't eat the budget and props up its weight viareward.
2. All 11 effect.type
The comments at the top of affixes.yml are the authoritative reference. One by one:
type | Effect | Params / fields |
|---|---|---|
mob-level-bonus | Spawn level +bonus (MM scales the stats itself; QR doesn't change values) | params: { bonus: <integer> } |
mob-count-mult | Spawn count ×mult (QR orchestrates quantity, not stats) | params: { mult: <multiplier> } |
player-status | Attaches vanilla potion effects to players in range (continuously refreshed) | params: { effect_name: level }, multiple allowed |
no-heal | No-heal rule: cancels all healing in range | params: {} |
time-limit | Time limit (seconds); the shortest is taken among multiple | params: { seconds: <seconds> } |
loot-quantity-mult | Cleanse drop quantity ×mult (multiplied with loot-bonus) | params: { mult: <multiplier> } |
unique-chance-mult | Weight of unique:true entries in the loot table ×mult | params: { mult: <multiplier> } |
currency-mult | Cleanse currency reward ×mult (via the CoreLib economy bridge) | params: { mult: <multiplier> } |
broadcast | Server-wide broadcast on activation | message: "..." (supports {ruin}/{tier}) |
command | Runs commands on present players on activation | commands: [ ... ] (supports {player}/{tier}) |
script | JS script custom logic | script: "qinhruins:file.js:function" |
Key points:
player-statusparams keys are vanilla potion effect names (e.g.SLOWNESS/WEAKNESS/DARKNESS/MINING_FATIGUE), and the values are levels (0= level I); multiple may be written. The effect refreshes every second, and the player keeps suffering it while within the realm range.- Affixes of the same type stack: multiple
mob-count-multmultipliers chain-multiply, multiplemob-level-bonussum, and multipletime-limittake the shortest. - A
commandaffix is written directly in yaml and run with console identity; ascriptaffix funnels to the developer scripts page: the logic lives inscripts/*.js, called by QR via CoreLib's GraalJS. See Affix Scripts (JS) for details.
command / script Affix Examples
# command affix ({player}=player name {tier}=tier)
blood-ritual:
name: "&4Blood Ritual"
danger: 25
reward: 20
min-tier: 3
effect:
type: command
commands:
- "effect give {player} minecraft:wither 200 0"
- "mm mobs spawn EliteBoss 1 {player}"
# JS script affix (logic in scripts/affix_example.js)
scripted-trial:
name: "&cTrial of Blood"
danger: 25
reward: 20
min-tier: 3
effect:
type: script
script: "qinhruins:affix_example.js:onActivate"3. Danger Budget
On activation QR rolls affix-count affixes by tier (see Realm & Keystone §3), subject to two constraints:
- Danger budget (danger-budget): the sum of all chosen affixes'
dangermust not exceed that tier's budget (tiers.danger-budget, default40 + tier*10). This prevents low-tier hell stacking — with a T1 budget of 50, you can't assemble a heavy combo like "No Heal (45) + Time Limit (30) + Horde (45)"; you have to climb to a high tier where the budget is enough.- The first affix is always guaranteed: the first affix is force-selected ignoring the budget, ensuring every realm has at least one affix.
- Writing
danger-budgetas≤0(or"0") = no budget limit.
- Same-group exclusion (group): once one affix is chosen, all other affixes in its same
groupare removed from the pool. For example, if "Elite Swarm" is chosen, "Horde" won't appear again (both belong to themob-countgroup).
The draw is weighted random: candidate affixes are drawn weighted by
danger+reward, then validated against the budget and exclusion. Affixes that don't satisfymin-tier/max-tiernever enter the candidate pool.
4. Exclusion Groups at a Glance
The two exclusion groups of the built-in affixes:
| group | Mutually exclusive members | Meaning |
|---|---|---|
mob-count | Elite Swarm / Horde | Spawn-count type, only one at a time |
mob-level | Veteran / Overlord | Mob-level type, only one at a time |
🖼️ [Image placeholder] Multiple affix names shown side by side at the top of the realm Bossbar (e.g. "Overlord Sands-of-Time Golden-Touch"), so the player reads this tier's modifiers at a glance · suggested
assets/affix-bossbar.png
For a new exclusion relationship, just give the affixes the same group string (any name works; same name means mutually exclusive).
5. The 13 Built-in Affixes
| id | Name | Category | group | danger / reward | min-tier | Effect |
|---|---|---|---|---|---|---|
elite-swarm | Elite Swarm | MOB | mob-count | 30 / 30 | 2 | Spawn count ×1.5 |
horde | Horde | MOB | mob-count | 45 / 45 | 5 | Spawn count ×2.0 |
veteran | Veteran | MOB | mob-level | 25 / 20 | 1 | Mob level +2 |
overlord | Overlord | MOB | mob-level | 40 / 35 | 4 | Mob level +5 |
oppression | Oppression | PLAYER | — | 20 / 15 | 1 | Slowness I + Mining Fatigue I |
enfeeble | Curse of Enfeeblement | PLAYER | — | 25 / 20 | 2 | Weakness I |
eternal-night | Eternal Night | ENV | — | 20 / 18 | 1 | Darkness (DARKNESS) |
brittle-ward | Brittle Ward | PLAYER | — | 45 / 40 | 5 | Disables all healing (no-heal) |
sands-of-time | Sands of Time | ENV | — | 30 / 30 | 3 | Time limit 5 minutes (300s) |
greed | Greed | LOOT | — | 0 / 50 | 1 | Loot quantity ×2.5 |
golden-touch | Golden Touch | LOOT | — | 0 / 45 | 1 | Currency drops ×3.0 |
hidden-trove | Hidden Trove | LOOT | — | 0 / 60 | 3 | Exclusive item drop rate ×3.0 |
herald | Realm Descent | ENV | — | 0 / 5 | 1 | Server-wide broadcast on activation |
affixes.ymlalso ships two commented-out examples,blood-ritual(command) andscripted-trial(script); just remove the#to enable them.
6. Don't Forget After Editing
- After editing
affixes.yml, run/qr reloadto apply. - LOOT-type affixes (Greed / Golden Touch / Hidden Trove) depend on the cleanse loot table and economy plugin configuration; for the setup see Loot System and Realm & Keystone §5.
- How affixes are rolled and how the danger budget loosens with tier → see Realm & Keystone.
Next Steps
- Configure the cleanse loot table (with
uniqueentries for "Hidden Trove" weighting) → Loot System - Write the JS logic for a
scriptaffix → Affix Scripts (JS) - Look up the built-in content list → Built-in Content List