Overview
The ClientModule class is the foundation for all modules (hacks) in LiquidBounce. It extends ToggleableValueGroup and implements EventListener, providing a complete framework for creating toggleable features with configuration and event handling.
Package: net.ccbluex.liquidbounce.features.module
Class Declaration
open class ClientModule(
name: String,
val category: ModuleCategory,
bind: Int = InputConstants.UNKNOWN.value,
bindAction: InputBind.BindAction = InputBind.BindAction.TOGGLE,
state: Boolean = false,
val notActivatable: Boolean = false,
val disableActivation: Boolean = notActivatable,
val disableOnQuit: Boolean = false,
aliases: List<String> = emptyList(),
hide: Boolean = false
) : ToggleableValueGroup(null, name, state, aliases = aliases), EventListener
Constructor Parameters
Module name displayed in UI and commands
Module category (Combat, Movement, Player, Render, World, Exploit, Misc, Fun)
bind
Int
default:"InputConstants.UNKNOWN.value"
Default keybind (use GLFW key constants)
bindAction
InputBind.BindAction
default:"TOGGLE"
Binding behavior: TOGGLE, HOLD, or SMART
If true, module cannot be toggled by user (utility modules)
disableActivation
Boolean
default:"notActivatable"
Prevents module from being enabled
Auto-disables module when leaving server
aliases
List<String>
default:"emptyList()"
Alternative names for the module
Default hidden state (hides from ArrayList)
Properties
Whether the module is actively running (enabled + in-game)override val running: Boolean
get() = super<EventListener>.running && inGame && (enabled || notActivatable)
Current keybind configuration
Whether module is hidden from ArrayList
Optional tag displayed in ArrayList (e.g., mode name)
Map of all module settings accessible by name@ScriptApiRequired
open val settings: Map<String, Value<*>>
Translation key prefix for this moduleoverride val baseKey: String = "${ConfigSystem.KEY_PREFIX}.module.${name.toLowerCamelCase()}"
Lifecycle Methods
onRegistration
open fun onRegistration()
Called when the module is registered in ModuleManager. Override to perform initialization.
onToggled
final override fun onToggled(state: Boolean): Boolean
Called when module state changes. Handles notifications and events. Do not override - use onEnable()/onDisable() instead.
enabledEffect
open suspend fun enabledEffect()
Launches an async coroutine task when module is enabled. Useful for repeating tasks.
Example:
override suspend fun enabledEffect() {
while (enabled) {
// Repeating task
delay(1000)
}
}
Inherited from ToggleableValueGroup
open fun onEnable()
open fun onDisable()
Override these methods to implement module enable/disable logic.
Methods
tagBy
fun tagBy(setting: Value<*>)
Sets a value to be displayed as the module tag.
Example:
val mode by choices("Mode", arrayOf("Speed", "Damage"), "Speed")
init {
tagBy(mode)
}
message
fun message(key: String, vararg args: Any): MutableComponent
Creates a translated message component for this module.
val msg = message("targetFound", targetName)
verifyFallbackDescription
fun verifyFallbackDescription()
Warns if module is missing translation description. Used during development.
Creating Modules
Basic Module
object ModuleExample : ClientModule(
name = "Example",
category = ModuleCategories.MISC
) {
override fun onEnable() {
chat("Module enabled!")
}
override fun onDisable() {
chat("Module disabled!")
}
}
Module with Settings
object ModuleFly : ClientModule(
name = "Fly",
category = ModuleCategories.MOVEMENT
) {
val speed by float("Speed", 1.0f, 0.1f..5.0f)
val mode by choices("Mode", arrayOf("Vanilla", "Damage"), "Vanilla")
override fun onEnable() {
// Use settings
player.abilities.mayfly = true
}
}
Module with Event Handlers
object ModuleAutoJump : ClientModule(
name = "AutoJump",
category = ModuleCategories.MOVEMENT
) {
val tickHandler = handler<GameTickEvent> {
if (player.onGround) {
player.jumpFromGround()
}
}
}
Module with Modes
object ModuleSpeed : ClientModule(
name = "Speed",
category = ModuleCategories.MOVEMENT
) {
private val modes = choices("Mode",
SpeedBHop,
SpeedStrafe,
SpeedYPort
)
object SpeedBHop : ChoiceConfigurable(this, "BHop") {
val speed by float("Speed", 1.0f, 0.1f..3.0f)
}
}
Best Practices
- Use descriptive names - Module names appear in UI and commands
- Set appropriate category - Helps users find your module
- Add keybinds for commonly used modules - Improves UX
- Use
disableOnQuit for modules that shouldn’t persist across sessions
- Implement
enabledEffect() for background tasks instead of tick handlers
- Use
tagBy() to show current mode in ArrayList
See Also