Skip to main content

Overview

Modules (also called “hacks”) are the core building blocks of LiquidBounce. Each module represents a specific feature or functionality that can be toggled on and off, configured with custom settings, and bound to keyboard keys for quick access.
All modules extend the ClientModule class defined in features/module/ClientModule.kt:53

Module Categories

LiquidBounce organizes modules into 8 distinct categories, each serving a specific purpose in gameplay enhancement.
Combat - Modules focused on player-versus-player combat scenariosExamples:
  • KillAura - Automatically attacks nearby enemies
  • Velocity - Modifies knockback behavior
  • Criticals - Forces critical hits on attacks
Defined in features/module/ModuleCategories.kt:28

Module Structure

Every module in LiquidBounce follows a consistent structure that enables configuration, event handling, and lifecycle management.

Core Properties

open class ClientModule(
    name: String,                    // Module display name
    category: ModuleCategory,        // One of the 8 categories
    bind: Int = UNKNOWN,            // Default keybind
    bindAction: BindAction = TOGGLE, // Bind behavior (TOGGLE, HOLD)
    state: Boolean = false,          // Default enabled state
    notActivatable: Boolean = false, // Can't be toggled
    disableActivation: Boolean = false,
    disableOnQuit: Boolean = false,  // Auto-disable when leaving world
    aliases: List<String> = emptyList(),
    hide: Boolean = false            // Hide from module list
)
Reference: features/module/ClientModule.kt:53-64

Module Lifecycle

1

Registration

When a module is first loaded, the onRegistration() method is called. This is where you should initialize any resources the module needs.
override fun onRegistration() {
    // Initialize module resources
}
Reference: ClientModule.kt:122
2

Toggling

When a module is enabled or disabled, onToggled() is called. This method handles state changes and fires events.
final override fun onToggled(state: Boolean): Boolean {
    // Handle enable/disable logic
    EventManager.callEvent(ModuleActivationEvent(name))
    EventManager.callEvent(ModuleToggleEvent(name, hidden, state))
    return state
}
Reference: ClientModule.kt:145-171
3

Enabled Effect

The enabledEffect() coroutine runs when the module is turned on, allowing for async initialization.
open suspend fun enabledEffect() {
    // Async tasks on module enable
}
Reference: ClientModule.kt:143
4

Running State

A module is considered “running” when it’s both enabled and the player is in-game.
override val running: Boolean
    get() = super<EventListener>.running && inGame && (enabled || notActivatable)
Reference: ClientModule.kt:74-75

Module Configuration

Modules can expose configurable settings through the value system:
val myBoolean by boolean("MyBoolean", true)
Settings can be accessed via scripts using module.settings.<settingname>

Real-World Example: KillAura

Here’s how a combat module is structured in practice:
object ModuleKillAura : ClientModule("KillAura", ModuleCategories.COMBAT) {
    
    // Attack speed and timing
    val clicker = tree(KillAuraClicker)
    val range = tree(KillAuraRange)
    val targetTracker = tree(KillAuraTargetTracker)
    
    // Rotation settings
    private val rotations = tree(KillAuraRotationsValueGroup)
    private val pointTracker = tree(PointTracker(this))
    
    // Requirements for attacking
    private val requires by multiEnumChoice<KillAuraRequirements>("Requires")
    
    // Bypass techniques
    internal val raycast by enumChoice("Raycast", TRACE_ALL)
    private val keepSprint by boolean("KeepSprint", true)
    
    // Inventory handling
    internal val ignoreOpenInventory by boolean("IgnoreOpenInventory", true)
    
    override fun onDisabled() {
        targetTracker.reset()
    }
}
Source: features/module/modules/combat/killaura/ModuleKillAura.kt:84-120

Tags and Display

Modules can display dynamic information on the HUD through tags:
open val tag: String?
    get() = this.tagValue?.getTagValue()?.toString()
Tags are automatically shown next to the module name in the ArrayList HUD element.
Use tagBy(setting) to automatically display a setting’s value as the module tag

Event Handling

Modules implement the EventListener interface, allowing them to handle game events:
val tickHandler = tickHandler {
    // Runs every game tick while module is enabled
}

val renderHandler = handler<WorldRenderEvent> { event ->
    // Runs on world render
}

Key Bindings

Each module can be bound to a keyboard key for quick toggling:
internal val bindValue = bind("Bind", InputBind(InputConstants.Type.KEYSYM, bind, bindAction))
Bind actions can be:
  • TOGGLE - Press once to enable, press again to disable
  • HOLD - Module is only active while key is held
Reference: ClientModule.kt:77-84

Best Practices

Group related settings using tree() to create organized configuration hierarchies.
val autoBlock = tree(KillAuraAutoBlock)
Always reset state in onDisabled() to prevent side effects:
override fun onDisabled() {
    targetTracker.reset()
    // Clean up resources
}
Control event handler execution order with priorities:
val handler = handler<GameTickEvent>(priority = Priority.IMPORTANT) {
    // High priority handler
}
Add description keys to translation files for user-facing documentation.

Next Steps

Commands

Learn about the command system for controlling modules

Scripts

Create custom modules using JavaScript or Python

API Reference

Explore the complete module API documentation

Examples

Follow tutorials for building your own modules

Build docs developers (and LLMs) love