Skip to content

Quality System

The quality system determines the tier of forged results. Quality affects material effect multipliers and optional item presentation changes.

Global configuration

yaml
quality:
  tiers:
    - name: "Common"
      weight: 60
      multiplier: 1.0
    - name: "Fine"
      weight: 30
      multiplier: 1.05
    - name: "Perfect"
      weight: 1
      multiplier: 1.2
  default_tier: "Common"
  guarantee:
    enabled: true
    threshold: 60
    minimum: "Flawless"

tiers format

The recommended form is one record per entry:

FieldTypeDescription
namestringUnique tier id and display name. Entries with a blank name are ignored.
weightintegerDraw weight; higher means more common. Must be greater than 0, otherwise the entry is ignored.
multipliernumberMultiplier applied to material effects (configured value × material amount × quality multiplier). Defaults to 1.0.

The "name-weight-multiplier" string form (split into three parts by -) is still accepted, but the record form above is the recommended configuration style.

If every tiers entry fails to parse, Forge falls back to the built-in default pool (a single 普通 tier with weight 100 and multiplier 1.0), with pity and item_meta both disabled.

Pity

The "fallback when key is absent" column below is what the code uses when the key is missing from your config. It differs from the shipped config.yml, which sets enabled: true, threshold: 60, and minimum: "无暇" — so the default configuration does have pity enabled.

FieldTypeFallback when key absentShipped valueDescription
guarantee.enabledbooleanfalsetrueWhether global pity is enabled.
guarantee.thresholdinteger1060Number of consecutive attempts below the minimum tier before pity triggers.
guarantee.minimumstring普通无暇Minimum quality tier granted when pity triggers.

Pity rules:

  • After each forge, the drawn tier's index in the quality pool is compared with the pity minimum tier's index.
  • If the drawn tier ranks lower, the pity counter increases by 1; otherwise it resets to 0.
  • Once the counter reaches threshold - 1, the next forge directly grants the pity tier and resets the counter.

Pity counters are tracked per player and recipe and stored in data/<player-uuid>.yml. The force mode of quality_modify skips all pity logic: it neither triggers pity nor updates the counter.

Item meta by quality

When item_meta.enabled is true, the result item receives quality-specific name operations, lore operations, and actions such as broadcasts.

yaml
quality:
  item_meta:
    enabled: true
    tiers:
      Perfect:
        name_actions:
          - action: "prepend_prefix"
            value: "<color:#FFD700>[Perfect] </color>"
        lore_actions: []
        action:
          - 'broadcastmessage text="<color:#FFD700>%player_name% forged a Perfect item!</color>"'
FieldDescription
name_actionsName operations applied per quality tier.
lore_actionsLore operations applied per quality tier.
actionAction lines executed per quality tier, such as a server-wide broadcast.

Deterministic calculation

Quality uses a deterministic algorithm: the tier is derived from a fingerprint of the player, recipe, and materials plus a preview seed, rather than rolling a fresh random number each time. Internally that roll key is hashed with SHA-256, and the first 12 hex characters are converted into a 0~1 ratio used for weighted selection over the quality pool.

The prepared forge result is cached with a 30-second TTL, so:

  • The quality shown in the GUI matches the actual forging result.
  • Resubmitting the same input within 30 seconds does not change the result.
  • Changing materials or waiting for the cache to expire changes the result.

Recipe override

Recipes can override global quality configuration under their own quality node. Note the recipe-level field names differ from the global config:

yaml
quality:
  enabled: true
  custom_pool:
    - "Common-50-1.0"
    - "Fine-35-1.08"
    - "Epic-15-1.25"
  guarantee:
    enabled: true
    attempts: 5
    minimum: "Fine"
FieldTypeDefaultDescription
enabledbooleanfalseWhether recipe-level quality configuration is enabled.
custom_poollist<string>emptyRecipe-specific quality pool using the "name-weight-multiplier" string form. Falls back to the global quality.tiers when empty.
guarantee.enabledbooleanfalseWhether recipe-level pity is enabled.
guarantee.attemptsinteger10Recipe-level pity threshold. Corresponds to threshold in the global config.
guarantee.minimumstring普通Recipe-level pity minimum tier.

When recipe-level pity is disabled but global pity is enabled, Forge falls back to the global threshold and minimum.

Interaction with material effects

  • variables effect value = configured value × material amount × quality multiplier
  • ea_attribute effect value = configured value × material amount × quality multiplier
  • The force mode of quality_modify skips pity evaluation and counter updates
  • The minimum mode of quality_modify raises the result only when the drawn tier is below the specified tier

See Materials for the full material effect syntax.