Null Bolt
Studio
guides

Rarities & affixes

Rarity is the power dial — affix counts, sockets, multipliers, and roll quality. Affixes are the vocabulary of bonuses, picked by weight under strict no-duplicate rules.

What a rarity controls

A RarityDefinition bundles every per-tier knob. The example set ships six: Common, Magic, Rare, Epic, Legendary, Unique.

FieldTypeDescription
Sort OrderintLower = more common. Used for minimum-rarity gating and UI ordering — not a drop probability.
Display Color / Border SpriteColor / SpriteCard tinting and border art.
Min/Max Random AffixesintHow many random affixes an item of this tier rolls.
Min/Max SocketsintSocket count range.
Stat Value MultiplierfloatScales every rolled stat value on the item.
Minimum Roll Qualityfloat 0–1Floor for the roll lerp — a 0.5 means every stat lands in the top half of its range.
Sell Value / Durability MultiplierfloatEconomy and durability scaling.
Can/Requires Legendary EffectboolWhether template legendary effects attach — and for Unique-style tiers, whether one is expected (and the unique name pool is used).
Max Name Affix Countint 0–20 = bare name, 1 = prefix, 2 = prefix + suffix in the generated name.
// heads up
There is no built-in drop table. The generator takes the rarity you pass it — deliberately, so your game's drop logic (level curves, magic find, pity timers) stays yours. A simple weighted roll over GeneratorSettings.AvailableRarities looks like this:
RarityRoller.cs — a minimal drop table
C#
using ItemGeneratorSystem;
using UnityEngine;

public static class RarityRoller
{
    // Pair each rarity with your drop weight, heaviest first.
    static readonly (string name, float weight)[] table =
        { ("Common", 60f), ("Magic", 25f), ("Rare", 10f), ("Epic", 4f), ("Legendary", 1f) };

    public static RarityDefinition Roll(GeneratorSettings settings)
    {
        float total = 0f;
        foreach (var e in table) total += e.weight;

        float pick = Random.value * total;
        foreach (var e in table)
        {
            if ((pick -= e.weight) <= 0f)
                return System.Array.Find(settings.AvailableRarities, r => r.RarityName == e.name);
        }
        return settings.AvailableRarities[0];
    }
}

Anatomy of an affix

An AffixDefinition grants one or more stat rolls and declares where it may appear:

FieldTypeDescription
Affix Name / Affix Typestring / Prefix|SuffixDisplay metadata for your tooltips (item names come from the separate name-generation pools, not from affix names).
Stat GrantsStatPoolEntry[]The stats + ranges this affix rolls. Every entry rolls.
WeightfloatSelection weight — heavier affixes appear more often.
Minimum Rarity / Allowed RaritiesgateTier gating: an explicit allowed-list wins; otherwise anything at or above the minimum qualifies.
Restricted To Types / Sub-TypesgateLimit an affix to weapons, rings, staves…
Exclusion GroupstringAt most one affix per group per item — e.g. one “damage conversion” family member.

The example content's 25 affixes show the patterns: 9 prefixes like Sharp and Vampiric, 7 suffixes like of Power and of the Fortress, four Magic-exclusive enchantments, and four Common-only Minor affixes that keep low-tier loot interesting without power creep.

How rolling works

The affix pipeline, in order
text
count   = random in [rarity.MinRandomAffixes .. rarity.MaxRandomAffixes]
filter  = tier gate ∩ type/sub-type gate ∩ granted stats ⊆ allowed stats
pick    = weighted selection, without replacement, skipping:
            · any affix whose ExclusionGroup is already used
            · any affix granting a stat the item already has
              (base stats, implicits, forced affixes, earlier picks)
roll    = per stat: quality = minQuality + rand × (1 − minQuality)
          value = lerp(min, max, quality) × rarity.StatValueMultiplier
          Flat → whole numbers; %/multiplier → 3 decimals; never a dead +0

Template forced affixes are rolled first and count against exclusion groups and stat uniqueness, so random picks never duplicate a signature stat. If the eligible pool runs dry before the rarity's minimum is met, the item still generates — with a console warning naming the rarity contract it couldn't meet.

Generated legendary item cards with affixes and legendary effects
High-tier rolls: rarity-tinted borders, implicits, affixes, sockets, and template legendary effects.
// note
One quality floor to remember: an item whose type has no base stats or implicits (jewelry, say) and rolls zero affixes would be a blank — the roller detects that case and forces one affix so every item does something.