Skip to main content

Overview

The ConfigSystem manages all configuration storage and retrieval in LiquidBounce. It provides a hierarchical system for organizing settings, supports JSON serialization, and handles config file management. Package: net.ccbluex.liquidbounce.config

Object Declaration

object ConfigSystem

Constants

KEY_PREFIX
String
default:"liquidbounce"
Prefix for all configuration keys
const val KEY_PREFIX = "liquidbounce"

Properties

rootFolder
File
Main configuration directory (.minecraft/LiquidBounce/)
val rootFolder: File
userConfigsFolder
File
User-created configs directory (.minecraft/LiquidBounce/configs/)
val userConfigsFolder: File
backupFolder
File
Backup configs directory (.minecraft/LiquidBounce/backups/)
val backupFolder: File
configs
ArrayList<Config>
List of all registered root configs
val configs: ArrayList<Config>
isFirstLaunch
Boolean
True if this is the first time LiquidBounce is launched
var isFirstLaunch: Boolean
    private set

Core Methods

Config Registration

root()
fun root(name: String, tree: MutableCollection<out ValueGroup>): Config
Creates and registers a root config.
fun root(name: String, tree: MutableCollection<out ValueGroup> = mutableListOf()): Config
Example:
val modulesConfig = ConfigSystem.root("modules", modules)
root()
fun root(config: Config): Config
Registers an existing config instance.
fun root(config: Config): Config

Config Storage

store()
fun store(config: Config)
Saves a config to its JSON file.
fun store(config: Config)
Example:
ConfigSystem.store(ModuleManager.modulesConfig)
storeAll()
fun storeAll()
Saves all registered configs.
fun storeAll()
Called automatically on world change and disconnect.

Config Loading

load()
fun load(config: Config)
Loads a config from its JSON file.
fun load(config: Config)
Example:
ConfigSystem.load(ModuleManager.modulesConfig)
loadAll()
fun loadAll()
Loads all registered configs.
fun loadAll()

Backup & Restore

backup()
fun backup(fileName: String, groups: Iterable<Config>)
Creates a ZIP backup of configs.
fun backup(fileName: String, groups: Iterable<Config> = this.configs)
Example:
ConfigSystem.backup("backup-2024-01-01")
restore()
fun restore(fileName: String)
Restores configs from a ZIP backup.
fun restore(fileName: String)
Example:
ConfigSystem.restore("backup-2024-01-01")

Value Lookup

findValueByKey()
fun findValueByKey(key: String): Value<*>?
Finds a value by its key path.
fun findValueByKey(key: String): Value<*>?
Example:
val value = ConfigSystem.findValueByKey("liquidbounce.module.killAura.range")
findValueGroupByKey()
fun findValueGroupByKey(key: String): ValueGroup?
Finds a value group by its key path.
fun findValueGroupByKey(key: String): ValueGroup?
valueKeySequence()
fun valueKeySequence(prefix: String): Sequence<String>
Returns sequence of all value keys with given prefix.
fun valueKeySequence(prefix: String): Sequence<String>
valueGroupsKeySequence()
fun valueGroupsKeySequence(prefix: String): Sequence<String>
Returns sequence of all value group keys with given prefix.
fun valueGroupsKeySequence(prefix: String): Sequence<String>

Serialization

serializeValueGroup()
fun serializeValueGroup(valueGroup: ValueGroup, gson: Gson): JsonObject
Serializes a value group to JSON.
fun serializeValueGroup(valueGroup: ValueGroup, gson: Gson = fileGson): JsonObject
deserializeValueGroup()
fun deserializeValueGroup(valueGroup: ValueGroup, jsonElement: JsonElement)
Deserializes JSON into a value group.
fun deserializeValueGroup(valueGroup: ValueGroup, jsonElement: JsonElement)
deserializeValue()
fun deserializeValue(value: Value<*>, jsonObject: JsonObject)
Deserializes JSON into a value.
fun deserializeValue(value: Value<*>, jsonObject: JsonObject)

Usage Examples

Creating a Config

object MyFeature {
    val enabled by boolean("Enabled", true)
    val speed by float("Speed", 1.0f, 0.1f..5.0f)
    val mode by choices("Mode", arrayOf("Fast", "Slow"), "Fast")
}

val myConfig = ConfigSystem.root("myfeature", mutableListOf(MyFeature))

Saving and Loading

// Save config
ConfigSystem.store(myConfig)

// Load config
ConfigSystem.load(myConfig)

// Save all configs
ConfigSystem.storeAll()

// Load all configs
ConfigSystem.loadAll()

Creating Backups

// Create backup
val timestamp = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Date())
ConfigSystem.backup("backup-$timestamp")

// Restore from backup
ConfigSystem.restore("backup-2024-01-01-12-00-00")

Finding Values

// Find value by key
val rangeValue = ConfigSystem.findValueByKey("liquidbounce.module.killAura.range")
if (rangeValue != null && rangeValue is RangedValue) {
    println("Range: ${rangeValue.get()}")
}

// Find value group
val killAura = ConfigSystem.findValueGroupByKey("liquidbounce.module.killAura")
if (killAura is ClientModule) {
    killAura.enabled = true
}

Iterating Values

// Get all values with prefix
val moduleValues = ConfigSystem.valueKeySequence("liquidbounce.module")
for (key in moduleValues) {
    val value = ConfigSystem.findValueByKey(key)
    println("$key = ${value?.get()}")
}

Config File Structure

Configs are stored as JSON files:
{
  "name": "modules",
  "value": [
    {
      "name": "KillAura",
      "value": [
        {
          "name": "Enabled",
          "value": true
        },
        {
          "name": "Range",
          "value": 4.2
        },
        {
          "name": "Mode",
          "active": "Single",
          "choices": {
            "Single": {
              "name": "Single",
              "value": []
            },
            "Multi": {
              "name": "Multi",
              "value": [
                {
                  "name": "MaxTargets",
                  "value": 3
                }
              ]
            }
          }
        }
      ]
    }
  ]
}

Automatic Config Management

Configs are automatically managed:
  1. On World Change - All configs saved
  2. On Disconnect - All configs saved
  3. On Client Shutdown - All configs saved
  4. On First Launch - Default configs created

Best Practices

  1. Register configs early - During initialization
  2. Use meaningful names - Config file names should be clear
  3. Group related settings - Use ValueGroups to organize
  4. Create backups before risky operations - Prevent data loss
  5. Handle load errors gracefully - Invalid configs shouldn’t crash
  6. Use normalized keys - Always use liquidbounce. prefix

Migration Support

ConfigSystem supports config migration for renamed values:
val newValue by float("NewName", 1.0f, aliases = listOf("OldName"))
When loading, if “NewName” is not found, ConfigSystem will look for “OldName”.

See Also

Build docs developers (and LLMs) love