How prerequisite checks actually work in Wrath of the Righteous
Grounded in the extracted game data: every number below is measured from the
client's own files — extracted/logic/prereq-semantics.json (decompile-verified
semantics) and extracted/logic/feature-prerequisites.jsonl (4,548 prerequisite
components across 2,147 features), build 20212986, patch 2.7.0x.
Taking a feat you "shouldn't" qualify for, or being blocked by one that looks legal on paper, comes down to one function the UI never shows you. This guide explains the machine's actual rules — including two behaviors that contradict most player-facing write-ups.
The short answer
When the game decides whether you can take a feature (feat, class ability,
arcane discovery…), it walks that feature's Components! array in declared
order, sorts every Prerequisite* component into two buckets, and evaluates:
canTake = (ALL-group passes) AND (ANY-group passes)
That is the entire algorithm. Everything else is which bucket a check lands in — and the bucket boundary is where the surprises live.
The two buckets — and the third that pretends to be one of them
Every prerequisite component carries a Group field: All, Any, or
ForcedTrue.
All— every check in the group must pass (AND).Any— at least one must pass (OR). An emptyAnygroup counts as passed.ForcedTrue— this is the interesting one. At the class level, a passingForcedTruecheck short-circuits the whole evaluation totrue, bypassing everything else. At the feature level,ForcedTruedegrades to plainAny— no short-circuit exists there.
The divergence is verified against the decompile:
BlueprintCharacterClass.IsAvailable implements the short-circuit;
BlueprintFeature.MeetsPrerequisites OR-folds ForcedTrue into the Any
accumulator without one. Practical consequence: a class gated with
ForcedTrue alignment can be force-opened by that single check; a feat with
the same component cannot.
What the checks look like in the shipped data
Across the 4,548 prerequisite components attached to 2,147 features, the ten most common are:
| Component | Count | What it asks |
|---|---:|---|
| PrerequisiteFeature | 1,233 | you own feature X |
| PrerequisiteNoFeature | 849 | you do NOT own feature X |
| PrerequisiteNoArchetype | 509 | you are not archetype X |
| PrerequisiteClassLevel | 448 | class X at level ≥ N |
| PrerequisiteStatValue | 286 | ability score ≥ N (pre-equipment) |
| PrerequisiteFeaturesFromList | 194 | ≥ N features from a list |
| PrerequisiteClassSpellLevel | 188 | can cast spells of level N |
| PrerequisiteArchetypeLevel | 163 | archetype X at level ≥ N |
| PrerequisiteCondition | 162 | a unit condition (e.g. Polymorphed) |
| PrerequisiteNoClassLevel | 160 | class X at level 0 |
Full inventory: logic/feature-prerequisites.jsonl
(see also the normalized planner view,
tools/feat-prereqs.json).
Stat checks compare base scores — not what your character sheet says
PrerequisiteStatValue reads the unit's base ability score: pre-equipment,
pre-buff, pre-level-up-bonus state. A +6 Perfection headband does not make you
Dex 18 for Dodge; a permanent +2 from a level-up does. This is the single most
common source of "the game let me / won't let me and the sheet disagrees"
reports — both sides of the argument are looking at different numbers.
(PrerequisiteFullStatValue is the rarer variant that does read the
current total; the dump marks which is which.)
Class-taking has its own rulebook
Class availability (IsAvailable) runs separate logic worth knowing before
multiclass or prestige planning:
- You cannot advance a class past level 20 (prestige classes cap at 10).
- While a mythic path is mandatory-pending (
NextObligatoryMythicClass), only that mythic class can be taken. - A class's alignment restriction is replaced wholesale by the first archetype you take with its own restriction — archetypes don't stack alignment gates, they overwrite them.
IgnorePrerequisites(the dev cheatignore_prereq) bypasses feature checks but only when not entering through progression replay.
Reading a feature's gates yourself
Every feature page on this database lists its prerequisite components from the
dump; the raw serialized form is in relations/feat-prereqs.json, the
normalized form in tools/feat-prereqs.json. When a pick fails validation in
our build planner, the failing group is the tooltip.
Sources
- Semantics (decompile-verified, 35 pin groups):
extracted/logic/prereq-semantics.json— schemaprereq-semantics-v1. - Component census:
extracted/logic/feature-prerequisites.jsonl. - Build: 20212986 (patch 2.7.0x). If the game patches, these datasets are regenerated by rerunning the extraction entrypoint, and this page is re-checked against the diff.