Skip to content

26.2 State Persistence and Config

Rifa edited this page Aug 21, 2026 · 1 revision

๐Ÿง  State Persistence & JSON Configuration

Parameter Specification
Config Manager Class net.instantgratification.collapsiblegamerules.GameRuleStateConfig
File Location .minecraft/config/collapsible-game-rules-state.json
Storage Structure Set<String> expandedCategories = new HashSet<>()
Serialization Engine com.google.gson.Gson (Pretty-Printing Enabled)
I/O Throttling Flag private static boolean isDirty = false
Flush Hook ScreenMixin targeting Screen.removed() (@At("HEAD"))
Persistence Key Strategy Localization Key (TranslatableContents.getKey()) or Literal String

๐Ÿ“– Overview

Collapsible Game Rules features an asynchronous, throttled state persistence engine. Rather than resetting to default expansion states every time a world or menu is opened, the mod remembers the exact categories you have expanded or collapsed across restarts.


๐Ÿ“„ JSON Configuration Format

The state is stored in a clean, human-readable JSON array inside .minecraft/config/collapsible-game-rules-state.json:

[
  "gamerule.category.spawning",
  "gamerule.category.mobs",
  "gamerule.category.updates"
]
  • Presence in Array: Indicates that the category is currently EXPANDED.
  • Absence from Array: Indicates that the category is currently COLLAPSED (default state).

โšก High-Performance I/O Throttling Architecture

Writing to disk on every mouse click or keyboard toggle creates unnecessary disk I/O and micro-stutter when players rapidly expand or collapse multiple categories.

To ensure zero frame drops, GameRuleStateConfig uses an isDirty state flag:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       THROTTLED PERSISTENCE WORKFLOW                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚   Player clicks Category Header                                             โ”‚
โ”‚        โ”‚                                                                    โ”‚
โ”‚        โ–ผ                                                                    โ”‚
โ”‚   GameRuleStateConfig.setExpanded(key, state)                               โ”‚
โ”‚        โ”œโ”€ Updates in-memory HashSet<String> in 0.0001 ฮผs                    โ”‚
โ”‚        โ””โ”€ Marks: isDirty = true (ZERO DISK I/O)                             โ”‚
โ”‚                                                                             โ”‚
โ”‚   Player closes Game Rules Screen (Esc, Done, or Cancel)                    โ”‚
โ”‚        โ”‚                                                                    โ”‚
โ”‚        โ–ผ                                                                    โ”‚
โ”‚   ScreenMixin.collapsible_game_rules$onRemoved()                            โ”‚
โ”‚        โ”‚                                                                    โ”‚
โ”‚        โ–ผ                                                                    โ”‚
โ”‚   GameRuleStateConfig.saveIfDirty()                                         โ”‚
โ”‚        โ”œโ”€ Checks: if (isDirty) { ... }                                      โ”‚
โ”‚        โ”œโ”€ Writes JSON to disk in background buffer                          โ”‚
โ”‚        โ””โ”€ Resets: isDirty = false                                           โ”‚
โ”‚                                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ’ป API & Method Reference

GameRuleStateConfig Public Methods

Method Signature Return Type Description
load() void Reads collapsible-game-rules-state.json on client startup (CollapsibleGameRulesFabricClient).
save() void Flushes the current expandedCategories set to disk via Files.newBufferedWriter.
saveIfDirty() void Saves to disk only if isDirty == true, then resets isDirty = false.
isExpanded(String categoryKey) boolean Checks if the given translation key is present in expandedCategories.
setExpanded(String categoryKey, boolean expanded) void Adds or removes the key from the set and sets isDirty = true if modified.
expandAll(Iterable<String> allKeys) void Adds all provided keys to the set in bulk and marks isDirty = true.
collapseAll() void Clears all entries from expandedCategories and marks isDirty = true.

๐Ÿ”’ Screen Removal Mixin Integration

State saving is hooked directly into Minecraft's base Screen.removed() method via ScreenMixin.java:

@Mixin(Screen.class)
public abstract class ScreenMixin {

    @Inject(method = "removed", at = @At("HEAD"))
    private void collapsible_game_rules$onRemoved(CallbackInfo ci) {
        if ((Object) this instanceof AbstractGameRulesScreen) {
            GameRuleStateConfig.saveIfDirty();
        }
    }
}

This guarantees that whenever the player exits the screenโ€”whether by clicking Done, Cancel, or pressing Escapeโ€”all modifications are safely preserved.


๐Ÿ”— Related Documentation

Clone this wiki locally