menus.yml

Every menu CoreJobs opens, laid out slot by slot.

Every item in this file takes the same fields:

Field What it does
material Minecraft material name, like DIAMOND or OAK_LOG
amount Stack size, defaults to 1
name Display name, with colour codes
lore List of lore lines
custom-model-data Resource pack model id, 0 to ignore
itemsadder Namespaced id like myitems:job_head, wins over material
head-texture Base64 texture, only used when the material is PLAYER_HEAD

Slots are 0-indexed. A six row menu has slots 0 to 53.

lang: routes work here too

Any name, lore line, or title written as lang:some.route is looked up in the player’s language file. A lore line pointing at a list expands into all of that list’s lines.

Block Menu
jobs-menu The /jobs grid
job-hub-menu A single job’s hub
job-tier-menu The tier and rewards page
boosts-menu Active boosts
shop-menu The farmpoints shop
ranking-menu The monthly ranking
jobs-menu:
  title: "lang:menu.jobs-title"
  rows: 6
  filler:
    material: GRAY_STAINED_GLASS_PANE
    name: " "
  profile:
    slot: 4
    material: PLAYER_HEAD
    use-player-head: true
  claim-all:
    slot: 48
    material: CHEST
  shop:
    slot: 49
    material: SUNFLOWER
  boosts:
    slot: 50
    material: EXPERIENCE_BOTTLE
  job-prestige:
    show: prestiged
    lines:
      - "lang:menu.job-prestige-lore"

Job icons themselves live in jobs.yml under each job’s icon and menu-slot.

job-prestige adds lines under a job icon carrying the prestige the viewer has in that job and what it is worth, so the grid shows it without opening the job. show takes prestiged (only a job this player has prestiged), always (every job with prestige turned on), or never. The lines take {prestige}, {maxprestige}, {prestige_pay}, {prestige_farmpoints}, {prestige_drops}, and {prestige_xp_cost} on top of the usual job placeholders.

job-tier-menu:
  rows: 6
  tier-slots: [10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25]
  achieved:
    material: LIME_STAINED_GLASS_PANE
  current:
    material: YELLOW_STAINED_GLASS_PANE
  locked:
    material: RED_STAINED_GLASS_PANE
  reward-claimable:
    material: LIME_STAINED_GLASS_PANE
  reward-claimed:
    material: GRAY_STAINED_GLASS_PANE
  reward-locked:
    material: RED_STAINED_GLASS_PANE
  claim-all:
    slot: 48
    material: CHEST
  previous-page:
    slot: 45
    material: ARROW
  next-page:
    slot: 53
    material: ARROW
  back:
    slot: 49
    material: BARRIER

tier-slots is the list of slots the level panes fill, in order. Shorten it for a tighter page or extend it to show more levels at once.

One page holds as many levels as tier-slots has slots, so a job with more levels than that is paged. previous-page and next-page are the two buttons that move between pages, and each takes the same fields as any other item.

Key Default slot When it shows
previous-page 45 Anywhere but the first page
next-page 53 While there are levels left to show

A button is left off the page it has nothing to do on, so the first page has no previous arrow. Keep both slots out of tier-slots, or a level pane covers the arrow.

claim-all claims every reward earned in this job, and back returns to the /jobs grid.

Button Default slot What it shows
leaderboard 10 Top players in the job. entries sets how many, capped by leaderboards.size
how-to-earn 12 The block or mob list, generated from jobs.yml
progress 14 The viewing player’s level, xp, and pay
prestige 16 Requirement lines, ticked or crossed
rewards 31 Opens the tier page
back 36 Returns to the /jobs grid

Generated lines sit between lore-header and lore-footer, so you control what wraps them.

how-to-earn.lines replaces the generated block and mob list with your own lines, for every job at once:

how-to-earn:
  slot: 12
  lore-header:
    - "lang:menu.how-to-earn-header"
    - ""
  lines:
    - "&7Break anything this job lists."
    - "&7Pay: &a{money}&7 each"
  lore-footer: []

Leave it empty for the generated list. {job}, {money} and {xp} work in a line, and so does a lang: route. A job can override this for itself with its own how-to-earn list in jobs.yml, which wins over both.

Written lines are static text. They do not recalculate per block the way the generated list does.

Key When it shows
lore-ready Every requirement met
lore-locked Something still missing
lore-maxed At the highest prestige
lore-disabled The job has prestige off and show-when-disabled is true

show-when-disabled: false hides the button entirely for a job with no prestige. disabled-material is the greyed-out material used when it is shown.

Placeholders in those lore lines: {prestige} {nextprestige} {maxprestige} {level} {maxlevel} {cost_money} {cost_xp_levels} {cost_farmpoints} {pay_bonus} {xp_cost_extra}.

ranking-menu:
  rows: 6
  header:
    ...
  entry-slots: [10, 11, 12, 13, 14, 15, 16]
  entry:
    ...
  last-entry-slots: [19, 20, 21, 22, 23, 24, 25]
  last-entry:
    ...
  claim:
    slot: 49
    material: CHEST
    name: "lang:menu.ranking-claim-name"
    lore-available:
      - "lang:menu.ranking-claim-available"
    lore-none:
      - "lang:menu.ranking-claim-none"

entry-slots holds this month’s heads and entry is the template each one is built from. last-entry-slots and last-entry do the same for the previous month’s row. Trim either list to show fewer places, or empty last-entry-slots to show only the current month. Both templates take {rank}, {player} and {points}.

The claim button has one name and two sets of lore, picked per viewer.

Key When it shows
lore-available The viewer has an unclaimed reward from last month. {rank} is the position they finished
lore-none Nothing to claim

Clicking only does something in the first state, so a player who finished outside the rewarded places sees the button but gets nothing from it.

shop-menu carries the balance icon, the filler, and the close button. Item slots come from shop.yml.

boosts-menu uses entry-slots for active boosts, an entry template, an entry-paused template for a boost waiting its turn, a none item for when nothing is running, and a back button. Both templates take {multiplier}, {type}, {job} and {remaining}, where {type} is the category. The entries redraw while the menu is open, so the time left ticks down on screen; the rate is feedback.boost-menu-refresh-ticks in config.yml.

Running boosts fill the slots first and waiting ones follow, so a player holding more boosts than there are entry-slots sees the running ones.

external is one item per category another plugin is boosting through the Developer API, filled into its own slots list in order, and only for a category reporting more than 1.0. Its lines take {type}, {multiplier} and {source}, where the source is the name that plugin gives itself. Nothing is drawn when no such plugin is registered, which is the normal case.

The line asks about all jobs, so a plugin boosting one job in particular reports its all figure here. The placeholders can still be asked per job.

  1. Turn on auto-reload
    auto-reload: true in config.yml, on by default.

  2. Open the menu in game
    Leave it open.

  3. Edit and save
    The menu rebuilds and reopens on the same page.

  4. Watch for slot clashes
    Two items on one slot means the last one loaded wins.

Rows and slots have to agree

A slot of 50 in a three row menu is out of range. Rows times nine is the slot count, so three rows stop at slot 26.