Skip to content

GUI Layouts

Files: config/frontier/guis/*.conf

Frontier’s GUIs are built on Ceremony’s ConfigGui system. Each GUI is defined in a HOCON config file that controls layout, items, actions, and pagination. All GUI files can be customized and hot-reloaded with /ranked reload.

FileGUI IDPurpose
hub.conffrontier:hubMain lobby — ladders, stats, season info.
ladder_dashboard.conffrontier:ladder_dashboardLadder details, player stats, queue controls.
leaderboard.conffrontier:leaderboardTop-ranked players on a ladder.
rewards.conffrontier:rewardsMilestones and season rewards.
rules.conffrontier:rulesFormat clauses and bans.
team_preview.conffrontier:team_previewTeam selection and opponent preview before battle.
challenge_invite.conffrontier:challenge_inviteAccept/decline incoming challenge.

Every .conf file follows this structure:

id = "frontier:gui_name"
title = "<!italic><gradient:#FFD700:#FFA500>Display Title</gradient>"
rows = 6
open-sound = "minecraft:block.chest.open"
state {
variable_name = "default_value"
}
watchers {
"variable_name" = [{type = "refresh"}]
}
areas = [
{ ... }
]
slots {
slot_id { ... }
}
FieldTypeDescription
idStringUnique GUI identifier (e.g., "frontier:hub").
titleStringWindow title, supports MiniMessage formatting.
rowsIntChest rows (1-6).
open-soundString?Sound played when the GUI opens.

Individual item slots at specific row/column positions. Each slot defines an item, optional visibility conditions, and click actions.

slots {
join_queue {
type = "button"
row = 4
col = 4
visible = "!frontier:in_queue && !frontier:in_match"
item {
stack = {id: "minecraft:lime_dye"}
name = "<!italic><green><bold>Join Queue</bold></green>"
lore = [
"<!italic><gray>Queue for a ranked match."
"<!italic><yellow>Click to join!"
]
}
actions {
left = [{type = "frontier:join_queue", value = "{state:ladder_id}", sound = "minecraft:block.note_block.chime"}]
}
}
}
FieldTypeDescription
typeStringSlot type. Usually "button".
rowIntRow position (0-based from top).
colIntColumn position (0-based from left, 0-8).
visibleString?Visibility condition. Omit = always visible.
item.stackObjectMinecraft item: {id: "minecraft:diamond"}.
item.nameStringDisplay name, MiniMessage format.
item.loreList<String>Lore lines, MiniMessage format.
actionsObjectClick handlers keyed by button (left, right).

Rectangular regions that can be filled with a repeating item or paginated data. Areas are defined in a list and rendered in order (later areas overlay earlier ones).

Fill a region with a static item — useful for backgrounds and dividers:

areas = [
{
id = "bg"
rows = [0, 1, 2, 3, 4, 5]
cols = [0, 1, 2, 3, 4, 5, 6, 7, 8]
fill {
stack = {id: "minecraft:black_stained_glass_pane"}
name = " "
}
}
]

Display dynamic data from a data source with automatic paging:

areas = [
{
id = "ladder_grid"
rows = [2, 3]
cols = [1, 2, 3, 4, 5, 6, 7]
pagination {
source = "frontier:active_ladders"
item-template {
type = "frontier:data_icon_button"
item {
stack = {id: "cobblemon:poke_ball"}
name = "<!italic><gold>{data:name}</gold>"
lore = [
"<!italic><gray>{data:description}"
"<!italic><gray>Format: <white>{data:format}"
"<!italic><yellow>Click to view"
]
}
actions {
left = [{type = "frontier:open_ladder", value = "{data:id}"}]
}
}
}
}
]

The frontier:data_icon_button widget type swaps the item’s visual appearance based on data while preserving the template’s name and lore.

State variables persist within the GUI session. They track context like which ladder is being viewed.

state {
ladder_id = ""
ladder_name = ""
}

Access state values in text with {state:variable_name}:

name = "<!italic><gold>{state:ladder_name}</gold>"

Trigger actions when state variables change:

watchers {
"ladder_id" = [{type = "refresh"}]
}

When ladder_id changes, the GUI refreshes to reflect the new ladder’s data.

Control when slots are shown or hidden. Conditions can be combined with && (and), || (or), and ! (not):

visible = "frontier:in_queue" # Show only when in queue
visible = "!frontier:in_queue && !frontier:in_match" # Show when idle
visible = "frontier:has_challenge" # Show when challenge pending
visible = "frontier:in_match && !frontier:in_queue" # Show when in match

Page-based visibility uses MoLang expressions:

visible = "molang:query.page('ladder_grid') < query.page_count('ladder_grid') - 1"
visible = "molang:query.page('ladder_grid') > 0"

Pagination templates use {data:field} to insert values from data providers.

{data:id}, {data:name}, {data:description}, {data:format}, {data:battle_type}, {data:team_size}

{data:position}, {data:name}, {data:rating}, {data:rank}, {data:wins}, {data:losses}, {data:winrate}

{data:name}, {data:level}, {data:ability}, {data:nature}, {data:types_line}, {data:move1} through {data:move4}, {data:iv_total}, {data:ev_total}, {data:iv_line1}, {data:iv_line2}, {data:ev_line1}, {data:ev_line2}, {data:gender}, {data:shiny}, {data:primary_hue}, {data:order_label}, {data:select_hint}, {data:index}

{data:name}, {data:progress}, {data:description}, {data:rewards}

{frontier_rating}, {frontier_rank}, {frontier_wins}, {frontier_losses}, {frontier_winrate}, {frontier_streak}, {frontier_season_name}, {frontier_season_end}, {frontier_season_remaining}, {frontier_queue_ladder}, {frontier_queue_size}, {frontier_challenges_status}, {frontier_ladder_level_cap}, {frontier_ladder_pick_count}

ActionDescription
frontier:join_queueJoin a ladder queue (value = ladder ID).
frontier:leave_queueLeave the current queue.
frontier:open_ladderOpen the ladder dashboard (value = ladder ID).
frontier:open_leaderboardOpen the leaderboard (value = ladder ID).
frontier:open_rewardsOpen the rewards GUI (value = ladder ID).
frontier:open_rulesView format rules (value = ladder ID).
frontier:accept_challengeAccept a pending challenge.
frontier:decline_challengeDecline a pending challenge.
frontier:select_pokemonSelect a Pokemon in team preview (value = index).
frontier:confirm_previewConfirm team selection.
frontier:surrenderForfeit the current match.
frontier:toggle_challengesToggle challenge invitations on/off.
frontier:handle_preview_closeHandle closing the preview (with optional delay).
open_guiOpen a GUI by ID (value = GUI ID).
page_nextNext page in pagination (value = area ID).
page_prevPrevious page in pagination (value = area ID).
closeClose the GUI.
refreshRefresh the GUI display.

Actions can include a sound field to play a sound on click:

actions {
left = [{type = "frontier:join_queue", value = "{data:id}", sound = "minecraft:block.note_block.chime"}]
}
  • Background areas should use stained glass panes with name = " " for clean layouts.
  • Use <dark_gray> box-drawing characters (like the ones in the default configs) to create visual structure in lore text.
  • The on-close field at the GUI root level runs actions when the GUI is closed — the team preview uses this to handle disconnects.
  • All text fields support the same MiniMessage formatting as messages.conf.