Skip to content

🗂️ Collapsible Categories

ParameterSpecification
System ComponentCollapsibleCategoryRuleEntry (Inner Class)
Enclosing MixinAbstractGameRulesScreenRuleListMixin
Target Classnet.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.RuleList
Indicator IconsExpanded: | Collapsed:
Count Badge Format (N rules) in ChatFormatting.GRAY
Hover Highlight Color0x22FFFFFF (25% Alpha White Box)
Separator Line Color0x44AAAAAA (Subtle Bottom Divider)
Text ColorHovered: 0xFFFFFFAA | Normal: 0xFFFFFFFF
Interaction Soundnet.minecraft.sounds.SoundEvents.UI_BUTTON_CLICK (Volume: 1.0F)
Narration TypeNarratedElementType.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:

java
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.

Official documentation & web portal for Dasik Igaijinn mods.