Skip to content

Category GUI ​

The layout file for the category-entry interface defines what players can do there and which placeholders each slot supports; how to write it is covered below

The category-entry codex is EmakiCodex's second codex model and is independent from the vanilla advancement pages in advancements/*.yml. You open it with /codex codex (or /codex open): the layout comes from gui/codex_gui.yml and the content from codex/*.yml

The full category field tables live in Configuration. What follows covers layout, interaction, and placeholders

Opening and permissions ​

ItemValue
Commands/codex codex, /codex open
Permissionemakicodex.use, or bypassed by emakicodex.admin
RestrictionsPlayers only; the GUI does not open when no valid category is loaded
Template idcodex_gui; opening fails with a warning when the template is missing

The four entry states ​

StateMeaningAvailable action
LockedNo unlock path has been satisfiedNone; hidden: true entries are not shown at all
UnlockedUnlocked but not activatedLeft click to activate
Activatedrewards.attributes is contributingRight click to claim the one-time reward
ClaimedThe one-time reward has been grantedNone (attribute rewards keep applying)

Keep the operation order in one sentence: activation and claiming are separate operations, activation only enables attribute rewards, and claiming only runs rewards.actions once. Attribute values are not stored; they are derived from the current codex/*.yml, so changing the configuration also changes already activated players

GUI template fields ​

gui/codex_gui.yml defines one template per file; id is the template name (this module always loads codex_gui). The template structure is parsed by CoreLib

FieldTypeRequiredDefaultAllowed valuesDescription
idstringYes—non-blank stringTemplate id; a blank id makes the template ignored. This module always loads codex_gui
gui_typestringNoCHESTan InventoryType name (such as CHEST)Inventory type; unknown values fall back to CHEST
titlestring / text configNoGUIMiniMessage string or text-config nodeInventory title
rowsintegerNo31 ~ 6Row count, clamped when out of range; applies only to row-supporting gui_type values, otherwise 0
slotsmapNoemptykeys are slot namesSlot definitions
slots.<name>.slotsstring / listYes—slot expression (such as "0-8", "10-16,19-25", [49])The slots this entry occupies; when empty the whole entry is ignored
slots.<name>.typestringNoinferred from the slot namesee Slot types belowFunctional slot type; codex_gui functional slots must declare it explicitly (entry, category_tab, and so on are not in the default inference table)
slots.<name>.itemmapNoemptyCoreLib item definition (source / amount / components, ...)Slot item; source accepts CoreLib ItemSource shorthand
slots.<name>.soundsmapNoemptyclick type → sound definitionOptional click sounds, such as left_click

Slot types ​

When writing a layout, remember one rule: functional slots must declare an explicit type, and a slot without type is purely decorative

typePurpose
entryEntry slot. All entry slots together form one page; out-of-range slots render as air. Left click activates, right click claims
category_tabCategory tab. Filled by ascending category order; out-of-range slots render as air. Clicking switches category and resets to page 1
page_prevPrevious page. Does nothing on the first page
page_infoPage information. The page number can only live here, never in the GUI title
page_nextNext page. Does nothing on the last page
closeCloses the GUI

The default template uses 10-16,19-25,28-34 for entries, which is 21 entry slots per page. Page size is derived from the number of entry slots you actually place, so changing the layout changes the page size

Placeholders ​

Available in entry slots:

PlaceholderMeaning
%entry_title%Entry title; replaced with the unknown-entry text while locked
%entry_description%Entry description; empty while locked
%entry_state%One of the four state labels
%entry_hint%Hint for the currently available action
%entry_rewards%Reward list, expanded to multiple lines (only when the line contains just this placeholder)
%codex_category%Category id
%codex_entry%Entry id

Category tabs can use %category_id%, %category_title%, and %category_state%. Page-info slots can use %current_page%, %total_pages%, %entry_count%, and %category_title%

Default layout excerpt ​

yaml
id: "codex_gui"
gui_type: CHEST
title: "<gradient:#D946EF:#F59E0B>Codex</gradient>"
rows: 6

slots:
  category_tab:
    type: "category_tab"
    slots: "0-8"
    item:
      components:
        custom_name: "%category_title%"
        lore:
          - "<gray>Category: <white>%category_id%</white></gray>"
          - "%category_state%"

  entry:
    type: "entry"
    slots: "10-16,19-25,28-34"
    item:
      components:
        custom_name: "%entry_title%"
        lore:
          - "%entry_description%"
          - "<gray>State: %entry_state%</gray>"
          - "%entry_rewards%"
          - "%entry_hint%"

  page_info:
    type: "page_info"
    slots: [49]
    item:
      source: "book"
      components:
        custom_name: "<gray>Page %current_page%/%total_pages%</gray>"

Locked entries render with a locked icon and the unknown-entry title, so there is no need to configure a separate slot for unknown entries