Enchanting Power
Custom Table Power
enchanting.table-power (in config.yml) replaces vanilla's enchanting table math end to
end: how "power" is measured around the table, and how that power turns into the three slot
levels shown in the enchanting UI. It only affects MythicEnchants' custom enchanting table —
vanilla enchanting tables are untouched.
Everything in this section is optional. Omit the whole block, or any piece of it, to fall back to vanilla behavior for that piece.
enchanting:
table-power:
materials:
BOOKSHELF: 1
require-line-of-sight: true
equations:
slot1: "floor(min(max((randomInt(1,8)+floor(count/2)+randomInt(0,count))/6, 1), 10))"
slot2: "floor(min((((randomInt(1,8)+floor(count/2)+randomInt(0,count))*2)/4)+1, 15))"
slot3: "floor(max(((randomInt(1,8)+floor(count/2)+randomInt(0,count))/2)+2, min(30, count*2)))"
slot-caps:
slot1: 10
slot2: 15
slot3: 30
max-base-level: 30
How it fits together
- Scan the positions around the table (vanilla's 30 bookshelf spots, or a custom
radiuscuboid) and sum a power weight (count) for every block that matches an entry inmaterials. - Feed
countinto the threeequations(one per enchanting-table slot) to get each slot's base level. - Clamp each slot's result to its
slot-capsentry. - Clamp the result one more time to the global
max-base-level.
Any step can be skipped by omitting its config — a skipped step just uses vanilla's own logic (vanilla scan positions, vanilla's power→level formula, vanilla's 10/15/30/30 caps).
materials — what counts as power
A map of block → power weight. Only blocks listed here contribute; everything else scanned is ignored, exactly like vanilla ignores every block except bookshelves.
materials:
BOOKSHELF: 1
EMERALD_BLOCK: 3
With the weights above, 5 bookshelves + 2 emerald blocks → count = 5*1 + 2*3 = 11.
Flat vs. state-weighted entries
A material's value can be a flat number (as above) or a map that weights the block by its block state:
materials:
CHISELED_BOOKSHELF:
default: 0 # weight when no rule below matches
states:
- match: "books>=3" # first match wins, evaluated top → bottom
weight: 2
- match: "books>=1"
weight: 1
matchis an exp4j expression (the same engineequationsuses — see below), evaluated against that block's state variables. Rules are tried in file order; the first one whosematchevaluates non-zero wins. If none match (or evaluation fails, e.g. an unbound variable), the block falls back todefault.- State variables come from the block's vanilla blockstate properties: booleans become
1/0(e.g.waterlogged). Numeric properties are exposed as-is. - Non-numeric enum properties (e.g.
facing=north) are not exposed — they can't be compared numerically, so there's nothing useful to bind them to. - A few blocks additionally expose derived variables. Currently:
booksforCHISELED_BOOKSHELF— the number of occupied slots,0–6.
Custom blocks (Nexo / MythicCrucible / ItemsAdder)
A materials key can reference an addon's custom block instead of a vanilla Material, using
the same nexo:<id> / crucible:<id> / itemsadder:<id> syntax the blockdrops and
customblock config sections use:
materials:
nexo:ruby_ore: 2
crucible:sapphire_block: 3
itemsadder:amethyst_lamp: 1
Rules for these entries:
- Flat weights only. There's no
states:support for addon blocks — their underlying carrier block has no state worth exposing. - Fallback only. A scanned position is checked against addon keys only if its plain
Materialisn't inmaterialsat all. Addon entries never shadow a vanillamaterialsentry. - Requires the addon plugin. If the corresponding plugin (Nexo, MythicCrucible, or
ItemsAdder) isn't installed, matching blocks simply contribute
0power — this never errors.
require-line-of-sight
When true, mirrors vanilla's air-gap rule: the cell directly between the table and a power
block must be air (or otherwise replaceable) for that block to count. This stops players from
cheesing the bonus with a solid wall between the table and a stack of bookshelves.
For the default vanilla-shaped scan, this is a straightforward "is the cell between the two
blocks clear" check. For a wide radius scan (see below), there's no single cell that sits
"between" the table and a shelf once the radius exceeds vanilla's, so the check approximates:
it requires the doorway cell at (table.x + sign(dx), table.y, table.z + sign(dz)) — i.e.
the cell adjacent to the table in the shelf's general direction — to be clear. A solid wall
built directly around the table still blocks the bonus in every direction; the approximation
only matters once shelves are further away than the doorway itself.
radius — custom scan shape
Optional. When omitted, the scan uses vanilla's hand-picked 30 positions — the exact set vanilla checks for bookshelves (8 directions × 2 Y-levels, with knight-move-style outer cells).
When present, it replaces that with a chebyshev-distance cuboid scan centered on the table:
radius:
inner: 2
outer: 7
y-min: 0
y-max: 1
| Key | Meaning |
|---|---|
inner |
Exclusive lower bound on max(|dx|, |dz|). 2 reproduces vanilla's rule that shelves can't be directly adjacent to the table. 0 lets blocks touching the table count. |
outer |
Inclusive upper bound on max(|dx|, |dz|). |
y-min / y-max |
Inclusive Y offsets relative to the table block. Vanilla's equivalent range is 0..1 (two layers). |
Every block position inside that cuboid whose chebyshev distance falls in (inner, outer] and
whose Y offset falls in [y-min, y-max] is scanned — a much larger and denser area than
vanilla's 30 fixed spots, useful for big libraries or shrine-style setups.
equations — power → slot level
Three exp4j expressions, one per enchanting-table slot (slot1/slot2/slot3, top → bottom in
the UI). Each has access to a single variable, count — the summed power from the scan step.
equations:
slot1: "floor(min(max((randomInt(1,8)+floor(count/2)+randomInt(0,count))/6, 1), 10))"
slot2: "floor(min((((randomInt(1,8)+floor(count/2)+randomInt(0,count))*2)/4)+1, 15))"
slot3: "floor(max(((randomInt(1,8)+floor(count/2)+randomInt(0,count))/2)+2, min(30, count*2)))"
Omit a slot's key (or the whole equations: block) to fall back to vanilla's own power→level
formula for that slot. If an equation throws at evaluation time (e.g. a bad expression), that
slot silently falls back to the vanilla formula rather than erroring for the player.
Available functions
floor,ceil,min,max,clamp(v, min, max)randomInt(a, b)— random integer, inclusive on both endsrandom(a, b)— random decimal in[a, b)- Standard math:
sin,cos,tan,asin,acos,atan,atan2(y, x),sinh,cosh,tanh,sqrt,cbrt,abs,exp,log,log2,log10,logb(x, base) - Extras:
todegree,toradian,step(edge, x),lerp(a, b, t),round,signum,sec,sech,csch - Standard operators including
^for exponentiation (count^2, notpow(count, 2))
This is the same expression engine used elsewhere in MythicEnchants' skill-line <math:...>
blocks.
slot-caps — per-slot ceiling
After a slot's equation evaluates, its result is clamped to a maximum. This exists mainly so you
don't have to wrap every equation in min(...) yourself.
slot-caps:
slot1: 10
slot2: 15
slot3: 30
- These defaults (
10/15/30) mirror vanilla's own per-slot progression. - Omitting the whole
slot-capsblock, or omitting a single slot's key, keeps that slot's default cap. - Set a slot to
0to opt it out of a per-slot cap entirely — only the globalmax-base-level(below) applies to it in that case.
max-base-level — global ceiling
A hard upper bound applied last, after everything above. Defaults to 30, matching vanilla's
enchanting-table UI.
Raising it above 30 works — the algorithm will genuinely reach for higher-tier enchants when
building the candidate pool, since the final enchant level is derived from this base level. The
tradeoff: the vanilla client renders the XP-cost number in red once it exceeds what a player
can normally reach, and confirming the enchant demands that many player levels. This is normal
Minecraft client behavior for an unexpectedly high level requirement, not something
MythicEnchants renders itself — set this carefully if you intend deeper progression than vanilla
allows.
See also
- Reagents can layer additional overrides on top of this base table-power calculation
(override or additive modes) — see the reagent documentation for
TablePowerOverride.