Despite the name, the runes.txt table does not hold the runes themselves — those live in Misc.txt (as items) and gems (as socket-stat sources). This table holds the runeword definitions: the recipe (which runes, in what order), what item types they apply to, what stats the resulting runeword grants, and whether it's enabled in the game.
181 rows total — every row carries a Name (Runeword1, Runeword2, …, Runeword181); there are no blank-Name placeholder rows or Expansion section marker like the affix files have. Of the 181, 99 are live in the current game (complete = 1); the remaining 82 are legacy or unused.
What's in a row
The 53 columns split into five groups.
Identity & display
| Column | Meaning |
|---|---|
Name | String key for the displayed runeword name when complete. The table values are internal keys (Runeword1 … Runeword181); the actual display name comes from the string-table lookup. |
*Rune Name | Resolved display name — Enigma, Spirit, Insight. The asterisk prefix marks this as an engine display column (loader artifact, not gameplay-relevant). |
*Patch Release | Game patch the runeword was added in (display only). |
Gating
| Column | Meaning |
|---|---|
complete | 1 = runeword is craftable in-game; 0 or blank = disabled. 99 of 181 rows are complete. |
disallowCraftingInLadder | 1 = explicitly forbidden on ladder realms. Rare — currently only Mosaic sets this (a post-launch balance override; it was originally a Season 3 ladder runeword but got disallowed mid-cycle). |
disallowCraftingInNonLadder | 1 = explicitly forbidden off-ladder. Currently 0 rows set this — non-ladder gating is achieved implicitly via firstLadderSeason. |
firstLadderSeason | Ladder-season number when the runeword was first introduced. This is the actual D2R ladder-gating mechanism: a runeword with firstLadderSeason set but no lastLadderSeason is ladder-only and has not yet rotated off-ladder (Cure, Bulwark, Hustle, Metamorphosis, Mosaic — the current D2R Ladder 3 additions, plus the Mosaic exception). 16 runewords have this set. |
lastLadderSeason | Final ladder season the runeword was ladder-exclusive. After this season ends, the runeword is released to non-ladder play. 8 runewords have both first and last set (Mist, Pattern, Plague, Wisdom, Flickering Flame, Unbending Will from D2R Ladder 1 with first=1, last=2; Mosaic with first=3, last=12). |
The disallow* columns are explicit forbid overrides (rare); the firstLadderSeason / lastLadderSeason window is the day-to-day mechanism that makes new runewords ladder-only and eventually releases them to non-ladder. A runeword complete=1 with firstLadderSeason set and no lastLadderSeason is currently ladder-only — that's how Cure and Bulwark work in 2026, even though no disallow* column is set.
Item-type filter
| Column | Meaning |
|---|---|
itype1 … itype6 | Allowed item types (itemtypes codes). Filled left-to-right; trailing slots blank. |
etype1 … etype3 | Excluded item types — used to carve exceptions out of an itype* allowance. |
The walk goes upward through the itype hierarchy. If a runeword allows tors (body armor) and you socket it in a Dusk Shroud (itype lite → tors), it works. If a runeword allows lite and you socket it in an Archon Plate (itype heav → tors), it doesn't — Archon Plate is heavy, not light. The walk only goes up the hierarchy, never sideways.
Rune sequence
| Column | Meaning |
|---|---|
*RunesUsed | Concatenated display string (JahIthBer for Enigma). Asterisk-prefixed display column. |
Rune1 … Rune6 | Required rune codes from Misc.txt (where runes are defined as items — the codes r01 through r33). The same codes appear in gems, which carries each rune's socket-stat data. Order matters — the runes must be socketed in this exact left-to-right order. |
Runeword length is determined by how many RuneN slots are filled. Distribution of the 99 complete runewords:
| Length | Count | Examples |
|---|---|---|
| 2 runes | 14 | Stealth, Steel, Lore, Smoke, Wind, Zephyr |
| 3 runes | 45 | Enigma (Jah-Ith-Ber), Lionheart, Treachery, Lawbringer, Crescent Moon |
| 4 runes | 25 | Spirit (Tal-Thul-Ort-Amn), Insight (Ral-Tir-Tal-Sol), Heart of the Oak, Infinity, Phoenix |
| 5 runes | 10 | Mist (Cham-Shael-Gul-Thul-Ith), Faith, Grief, Death, Call to Arms |
| 6 runes | 5 | Last Wish (Jah-Mal-Jah-Sur-Jah-Ber), Breath of the Dying, Silence, Obsession, Unbending Will |
Stat block
| Column | Meaning |
|---|---|
T1Code1 … T1Max7 | Up to 7 stats. Same Code / Param / Min / Max pattern as everywhere else. Code is a property name from Properties.txt (which composes one or more itemstatcost stats with display logic). Param is stat-specific — a numeric ID for some properties (skill IDs for oskill/chargedskill), or a skill name string for others (e.g. Authority's gethit-skill carries Psychic Ward as Param, hit-skill carries Miasma Chains). Min/Max is the value range — equal for fixed values, otherwise the runeword rolls within. |
T1 is a holdover from a planned multi-tier system that never shipped — there is no T2 block.
Asterisk columns
*Rune Name, *RunesUsed, *Patch Release, *eol are all engine display/marker columns — the asterisk prefix signals to the loader that they're for display or file-format housekeeping, not gameplay. The runeword's actual identity is Name (Runeword42); the runes-used data is in Rune1–Rune6. Don't query against asterisk columns expecting strict gameplay semantics.
Variable rolls
Most runewords are fully determined — Enigma's +2 to all skills is always +2. But some have Min < Max on one or more stats and roll within that range:
| Runeword | Variable stat | Range |
|---|---|---|
| Grief | dmg (added damage) | 340–400 |
| Heart of the Oak | res-all | 30–40 |
| Faith | aura (Fanaticism level) | 12–15 |
When reporting rolls, always show the range, not the average.
Worked example: Enigma
The canonical body-armor runeword. *Rune Name = Enigma, Name = Runeword<N>:
| Column | Value | Notes |
|---|---|---|
complete | 1 | Live in the game. |
itype1 | tors | Allowed on any body armor (the tors itype matches every body subtype via the upward hierarchy walk). |
Rune1 / Rune2 / Rune3 | r31 / r06 / r30 | Jah, Ith, Ber — the 3-rune sequence. |
*RunesUsed | JahIthBer | Display-only confirmation. |
T1Code1 / Param1 / Min1 / Max1 | allskills / blank / 2 / 2 | +2 to all skills (fixed). |
T1Code2 / Param2 / Min2 / Max2 | move3 / blank / 45 / 45 | +45% Faster Run/Walk (fixed). |
| (further T1 slots) | telep, dmg%, def%, mag%, str/lvl … | The full 7-slot block carries Enigma's other mods (Teleport oskill, +750-775 defense, +0.75% MF/clvl, etc.) |
The engine validates the socket sequence (left-to-right rune codes match Rune1–Rune6), confirms the item type matches (tors walked upward from the specific body-armor base), then applies the seven T1* stats.
Gotcha: rune order matters
Runewords must be socketed in left-to-right rune order. Stealth in body armor is Tal-Eth (r07, r05) — socketing Eth-Tal does not produce Stealth, just two socketed runes with their individual stats. The engine reads sockets left-to-right and matches against the Rune1–Rune6 sequence; any mismatch fails silently.
Cross-references
gems—Rune1–Rune6codes (r01–r33) match the rune entries here, which carry the socket-stat data when a rune is socketed elsewhere. Note runes-as-items also live inMisc.txtwith the same codes.itemtypes—itype*/etype*reference the item-type taxonomy.itemstatcost—T1Code*ultimately resolves to stat IDs defined here (via Properties.txt).cubemain— rune-upgrade recipes (3 ×r12 → 1 ×r13) feed the runes that go into runewords.Properties.txt— defines what eachT1Code*resolves to (one or moreitemstatcoststats with display logic).Misc.txt— defines runes as inventory items (theRune1–Rune6columns reference thecodefield there).