Skip to content

26.2 Collapsible Categories

Rifa edited this page Aug 21, 2026 · 1 revision

๐Ÿ—‚๏ธ Collapsible Categories

Parameter Specification
System Component CollapsibleCategoryRuleEntry (Inner Class)
Enclosing Mixin AbstractGameRulesScreenRuleListMixin
Target Class net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.RuleList
Indicator Icons Expanded: โ–ผ | Collapsed: โ–ถ
Count Badge Format (N rules) in ChatFormatting.GRAY
Hover Highlight Color 0x22FFFFFF (25% Alpha White Box)
Separator Line Color 0x44AAAAAA (Subtle Bottom Divider)
Text Color Hovered: 0xFFFFFFAA | Normal: 0xFFFFFFFF
Interaction Sound net.minecraft.sounds.SoundEvents.UI_BUTTON_CLICK (Volume: 1.0F)
Narration Type NarratedElementType.TITLE (NarrationPriority.HOVERED)

๐Ÿ“– Overview

In vanilla Minecraft, the Game Rules screen renders category headers as static, non-interactive text labels (CategoryRuleEntry), with all child rules listed sequentially in a single scrolling pane. When mods add dozens of custom GameRules, the screen becomes excessively long and difficult to navigate.

Collapsible Categories replaces static headers with interactive CollapsibleCategoryRuleEntry widgets that can be expanded or collapsed at will.


๐ŸŽจ Visual Layout & Hierarchy

When rendered inside the RuleList, each category header features dynamic visual indicators and status badges:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ [ Expand All ]                                             [ Collapse All ] โ”‚ โ—„โ”€โ”€ GlobalActionsRuleEntry (Index 0)
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ–ผ โš”๏ธ Mobs (14 rules)                                                        โ”‚ โ—„โ”€โ”€ CollapsibleCategoryRuleEntry (Expanded)
โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚
โ”‚   mobGriefing                                                     [ ON ]    โ”‚ โ—„โ”€โ”€ Child RuleEntry
โ”‚   doMobSpawning                                                   [ ON ]    โ”‚ โ—„โ”€โ”€ Child RuleEntry
โ”‚   doMobLoot                                                       [ ON ]    โ”‚ โ—„โ”€โ”€ Child RuleEntry
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ–ถ ๐Ÿ‘ค Player (8 rules)                                                       โ”‚ โ—„โ”€โ”€ CollapsibleCategoryRuleEntry (Collapsed)
โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚
โ”‚ โ–ผ ๐ŸŒง๏ธ Updates (6 rules)                                                      โ”‚ โ—„โ”€โ”€ CollapsibleCategoryRuleEntry (Expanded)
โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚
โ”‚   doFireTick                                                      [ ON ]    โ”‚ โ—„โ”€โ”€ Child RuleEntry
โ”‚   randomTickSpeed                                                 [ 3  ]    โ”‚ โ—„โ”€โ”€ Child RuleEntry
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โš™๏ธ Technical Mechanics

1. Child Rule Counting Algorithm

When updateVisibleEntries() iterates through allEntries, it determines the exact number of child rules belonging to a category before the next category begins:

int childCount = 0;
for (int j = i + 1; j < this.collapsible_game_rules$allEntries.size(); j++) {
    if (this.collapsible_game_rules$allEntries.get(j) instanceof AbstractGameRulesScreen.CategoryRuleEntry) {
        break;
    }
    childCount++;
}

2. Category Rendering Pipeline (extractContent)

The rendering process is executed via Minecraft's modern GuiGraphicsExtractor interface:

  1. Hover Box: If the cursor hovers over the category entry, a semi-transparent box (0x22FFFFFF) is drawn across [getX() - 2, getY()] to [getX() + getWidth() + 2, getY() + 24].
  2. Directional Arrow & Text: The prefix (โ–ผ if expanded, โ–ถ if collapsed) is prepended to the category label, followed by the gray child count badge ( (N rules)).
  3. Centered Alignment: The combined component is drawn centered horizontally at getContentXMiddle() with vertical offset getContentY() + 5.
  4. Bottom Divider: A subtle dividing line (0x44AAAAAA) is drawn at getY() + 23 across the entry width to demarcate category boundaries.

3. Mouse Interaction Handling

The category header captures mouse clicks in mouseClicked(MouseButtonEvent event, boolean doubleClick):

  • Left Click (event.button() == 0) or Right Click (event.button() == 1):
    1. Invokes the category's toggleAction.run().
    2. Updates GameRuleStateConfig with the new boolean state.
    3. Plays the vanilla UI click sound: SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F).
    4. Triggers updateVisibleEntries() to dynamically add or remove child rule entries from the active list.
    5. Recalculates list dimensions via updateSizeAndPosition(...).

4. Accessibility & Screen Narration

CollapsibleCategoryRuleEntry implements NarratableEntry:

  • Priority: NarrationPriority.HOVERED
  • Narration Output: Pushes the category label as NarratedElementType.TITLE to ensure screen readers narrate the active category name when focused or hovered.

๐Ÿ”— Related Documentation

Clone this wiki locally