Config

settings:
  debug: false
  check-for-updates: true
  language: "en_US"
  fancy-splash: true

datapack:
  enabled: true
  auto-generate: true
  install-on-startup: true
  datapack-name: "MythicEnchants"
  # If left blank, installs to all loaded worlds dynamically.
  # Otherwise, list specific world names below.
  worlds: []
  # - "world"
  regenerate-on-reload: true
  # We NEVER run /reload. Auto-reload will never be an option.
  max-backups: 0

items:
  max-enchantments-per-item: 16

anvil:
  bypass-too-expensive: true
  free-anvil-use: false
  allow-combining: true
  cost-multiplier: 1.0

grindstone:
  allow-removal: true
  xp-return-percent: 100
  keep-curses: true

enchanting:
  # Disables MythicEnchants providing its own emulated enchanting table.
  # Required for reagents and conditional enchanting.
  # All enchantments are registered using vanilla datapack offering settings.
  custom-table: true
  # Vanilla-override: register treasure enchants as offered in the table.
  allow-treasure: false
  # Whether vanilla enchantments can appear in the custom enchanting table.
  # When false (default), only custom MythicEnchants enchantments are offered.
  # When true, vanilla enchantments are filtered using datapack supported_items
  # tags (authoritative item-type check) and can fill slots that have no custom
  # enchantment available.
  vanilla-in-table: true
  # When true, an empty reagent slot is treated as if vanilla lapis were
  # present — offers are computed against the "vanilla" reagent bucket and
  # shown immediately when the player drops in an item. When false (default),
  # the table waits until the player adds *something* to the reagent slot
  # before producing offers (vanilla lapis still rolls vanilla-bucket offers,
  # custom reagents roll their own bucket). Use `true` for the legacy
  # always-show behavior; `false` for a reagent-gated UX.
  assume-reagent-lapis: false
  # Custom-table only. Replaces vanilla's hard-coded "1 power per bookshelf,
  # capped at 15" with a configurable material weight map and three per-slot
  # equations evaluated against a `count` variable.
  #
  #   * `materials` — block ID → power weight. Any block listed here is counted
  #                   at the same 30 positions vanilla scans for bookshelves.
  #                   The value is summed (e.g. 5 BOOKSHELF + 2 EMERALD_BLOCK
  #                   with the weights below → count = 5*1 + 2*3 = 11).
  #   * `require-line-of-sight` — when true, follows vanilla's air-gap rule
  #                   (the cell between the table and a power block must be
  #                   air). Stops players cheesing with solid walls.
  #   * `equations` — exp4j expressions for slot1/slot2/slot3 (top→bottom in
  #                   the table UI). Variable `count` is the summed power.
  #                   Functions: `floor`, `ceil`, `min`, `max`, `clamp`,
  #                   `randomInt(a,b)` (inclusive), plus all standard math.
  #                   Omit a slot's equation to fall back to the vanilla
  #                   formula for that slot.
  table-power:
    materials:
      BOOKSHELF: 1
      # EMERALD_BLOCK: 3
    require-line-of-sight: true
    # Optional. When omitted, scans vanilla's hand-picked 30 positions (the
    # exact set vanilla uses for bookshelves). When present, replaces that
    # with a chebyshev-distance cuboid scan around the table.
    #
    #   inner — exclusive lower bound on max(|dx|,|dz|). 2 reproduces vanilla's
    #           "shelves can't be adjacent to the table" gap. 0 lets blocks
    #           directly 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 equivalent is 0..1 (two layers).
    #
    # LOS rule for wide radii: there's no single "cell between table and shelf"
    # once the radius exceeds 2, so the check approximates by requiring the
    # cell at (sign(dx), 0, sign(dz)) — the doorway adjacent to the table —
    # to be replaceable. Solid wall around the table still kills the bonus.
    # radius:
    #   inner: 2
    #   outer: 7
    #   y-min: 0
    #   y-max: 1
    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)))"
    # After each slot's equation evaluates, clamp the result to this maximum.
    # Saves wrapping every equation in min(...). Defaults shown below
    # (10/15/30) mirror vanilla's progression. To opt a slot out of its cap
    # so only the global `max-base-level` applies, set it to `0`. Omitting
    # the entire block keeps the defaults; omitting a single slot also
    # keeps that slot's default.
    slot-caps:
      slot1: 10
      slot2: 15
      slot3: 30
    #
    # Hard upper bound applied last — defaults to 30 to match vanilla's
    # enchanting-table UI. Lifting beyond 30 works (the algorithm will pick
    # higher-tier enchants for the candidate pool) but the XP-cost number
    # renders in red and demands that many player levels to confirm. Set
    # carefully if you want deeper progression than vanilla allows.
    max-base-level: 30

cleanup:
  disabled-enchants:
    enabled: true
    remove-from-items: true

storage:
  # Supported types: YAML, JSON, SQLITE
  type: "YAML"
  auto-save-interval: 12000
  save-on-quit: true

legacy:
  # When true, enchantment files written in the old v1 schema (top-level Weight/MinCost,
  # AdditionalPerLevelCost, ItemType, Options.OfferedInEnchantingTable, list-form
  # SupportedItems, Rarity: CURSE) are auto-upgraded in memory at load time and rewritten
  # to disk in the modern format. The original file is preserved as <name>.yml.bak the
  # first time the rewrite runs. Set to false to keep the file untouched on disk; the
  # in-memory upgrade still happens so the enchantments load correctly either way.
  rewrite-on-load: true
Updated Aug 19, 2026