Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CCBlueX/LiquidBounce/llms.txt

Use this file to discover all available pages before exploring further.

This guide provides tips and techniques for debugging LiquidBounce during development.

Development Environment

IDE Setup

IntelliJ IDEA offers the best Kotlin debugging experience:
  1. Open as Gradle Project
    • File → Open → Select LiquidBounce directory
    • Let Gradle sync complete
  2. Generate Sources (Optional but Recommended)
    ./gradlew genSources
    
    This decompiles Minecraft code for easier debugging.
  3. Enable Auto-Import
    • Settings → Build, Execution, Deployment → Build Tools → Gradle
    • Enable “Auto-import”

Running with Debugger

Method 1: Gradle Task

  1. Open Gradle panel (View → Tool Windows → Gradle)
  2. Navigate to: LiquidBounce → fabric → runClient
  3. Right-click → Debug ‘LiquidBounce [runClient]‘

Method 2: Run Configuration

  1. Edit Configurations+Gradle
  2. Configure:
    • Name: Debug LiquidBounce Client
    • Gradle project: LiquidBounce
    • Tasks: runClient
    • VM options: -Xmx4G (optional, for more memory)
  3. Click Debug button

Debugging Techniques

Breakpoints

Set breakpoints in your code to pause execution:
fun onEnable() {
    // Set breakpoint on next line
    player.sendMessage("Module enabled")
}
Setting Breakpoints:
  • Click in the left margin next to the line number
  • Or press Ctrl+F8 (Windows/Linux) or ⌘+F8 (Mac)

Conditional Breakpoints

Break only when certain conditions are met:
  1. Right-click a breakpoint
  2. Enter condition (e.g., player.health < 5.0)
Useful for debugging specific scenarios without stopping every time.

Logging Breakpoints

Log messages without stopping execution:
  1. Right-click a breakpoint
  2. Check “Evaluate and log”
  3. Enter expression to log
  4. Uncheck “Suspend”

Evaluate Expression

While paused at a breakpoint:
  • Alt+F8 (Windows/Linux) or ⌥+F8 (Mac)
  • Type any Kotlin/Java expression
  • See immediate results
Examples:
player.inventory.mainHandStack
world.players.size
mc.currentScreen?.javaClass?.simpleName

Console Logging

Using LiquidBounce Logger

import net.ccbluex.liquidbounce.utils.client.logger

// Info level
logger.info("Player position: ${player.pos}")

// Debug level
logger.debug("Checking target: $targetEntity")

// Warning level
logger.warn("Invalid configuration value")

// Error level
logger.error("Failed to load module", exception)

Minecraft Logger

import org.apache.logging.log4j.LogManager

val LOGGER = LogManager.getLogger("LiquidBounce")

LOGGER.info("Custom log message")

Chat Messages (In-Game Debugging)

import net.ccbluex.liquidbounce.utils.client.chat

// Simple message
chat("Debug: $value")

// Colored message
chat("§aSuccess: §7$message")

// Without prefix
chat(message, prefix = false)

Common Debugging Scenarios

Debugging Modules

Module Not Working

  1. Check if enabled
    logger.info("Module enabled: $enabled")
    
  2. Verify event handlers
    val attackHandler = handler<AttackEvent> { event ->
        logger.info("Attack event triggered")
        // Your code
    }
    
  3. Check conditions
    if (!enabled) {
        logger.debug("Module disabled, skipping")
        return@handler
    }
    

Module Settings Not Saving

  1. Check config serialization
  2. Verify value changes:
    val range by float("Range", 4.0f, 1.0f..6.0f)
        .onChange { oldValue, newValue ->
            logger.info("Range changed: $oldValue -> $newValue")
            true // Accept change
        }
    

Debugging Events

Event Not Firing

  1. Verify event handler registration
    val handler = handler<PlayerTickEvent> { event ->
        logger.info("Tick event fired")
    }
    
  2. Check event sequence
    val handler = sequenceHandler<PlayerTickEvent> { event ->
        logger.info("Sequence handler called")
        // Your code
    }
    
  3. Ensure module is enabled - Handlers typically only fire when module is enabled

Event Firing Too Often

Use throttling or debouncing:
private var lastCheck = 0L

val handler = handler<PlayerTickEvent> {
    val now = System.currentTimeMillis()
    if (now - lastCheck < 1000) return@handler // Throttle to 1 second
    lastCheck = now
    
    // Your code
}

Debugging Rendering

Rendering Not Showing

  1. Check render event
    val renderHandler = handler<WorldRenderEvent> { event ->
        logger.debug("Render event triggered")
        renderEnvironmentForWorld(event.matrixStack) {
            // Your rendering
        }
    }
    
  2. Verify coordinates
    logger.info("Rendering at: ${pos.x}, ${pos.y}, ${pos.z}")
    
  3. Check GL state - Ensure proper GL setup

Debugging Mixins

Mixin Not Applying

  1. Check mixin configuration in fabric.mod.json
  2. Verify target class
    @Mixin(ClientPlayerEntity.class)
    public class MixinClientPlayerEntity {
        // Ensure class name is correct
    }
    
  3. Check injection point
    @Inject(method = "tick", at = @At("HEAD"))
    private void onTick(CallbackInfo ci) {
        System.out.println("Mixin injected!");
    }
    
  4. Review Mixin logs - Check console for mixin application errors

Performance Debugging

Profiling

JVM Profiler

Use IntelliJ’s built-in profiler:
  1. Run → Profile ‘LiquidBounce [runClient]’
  2. Analyze CPU and memory usage
  3. Identify bottlenecks

Manual Timing

import kotlin.system.measureTimeMillis

val duration = measureTimeMillis {
    // Code to measure
    performExpensiveOperation()
}

logger.info("Operation took ${duration}ms")

Memory Leaks

Check for Retained References

  1. Take heap dump after running for a while
  2. Analyze with Memory Profiler
  3. Look for growing collections or unclosed resources

Common Issues

  • Event handlers not unregistered
  • Static collections growing unbounded
  • Cached data not cleared

Remote Debugging

Attach Debugger to Running Instance

  1. Add JVM arguments
    ./gradlew runClient -Dorg.gradle.jvmargs="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
    
  2. Create Remote Debug Configuration in IntelliJ
    • Run → Edit Configurations → + → Remote JVM Debug
    • Host: localhost
    • Port: 5005
  3. Attach debugger when client is running

Build Debugging

Gradle Build Issues

Enable Debug Logging

./gradlew build --debug > build.log 2>&1
Review build.log for detailed information.

Clean and Rebuild

./gradlew clean build

Check Dependency Resolution

./gradlew dependencies

Theme Build Issues

Manual Theme Build

cd src-theme
npm install
npm run build

Check Node.js Version

node --version
npm --version
Ensure you’re using a compatible version.

Testing and Validation

Run Tests with Debugging

./gradlew test --debug-jvm
Then attach debugger on port 5005.

Code Quality Checks

Run Detekt

./gradlew detekt
Fix any violations before debugging further.

Verify i18n

./gradlew verifyI18nJsonKeys

Common Issues and Solutions

Client Won’t Start

  1. Check JDK version
    java -version  # Should be 21 or higher
    
  2. Verify Gradle sync completed in IDE
  3. Regenerate sources
    ./gradlew cleanLoom genSources
    

ClassNotFoundException

  1. Rebuild project
    ./gradlew clean build
    
  2. Invalidate caches (IntelliJ: File → Invalidate Caches)
  3. Check dependencies in build.gradle.kts

Crashes

  1. Check crash log in crash-reports/ directory
  2. Look for stack trace in console
  3. Identify last executed code before crash
  4. Reproduce with minimal code to isolate issue

Debugging Tools

In-Game Commands

Use LiquidBounce commands for live debugging:
.help              # List all commands
.toggle <module>   # Toggle module for testing
.binds             # Show module bindings

External Tools

  • VisualVM: JVM monitoring and profiling
  • JProfiler: Advanced profiling
  • YourKit: Performance analysis
  • MAT (Memory Analyzer Tool): Heap dump analysis

Best Practices

  1. Use meaningful log messages - Include context
  2. Remove debug logs before committing
  3. Use proper log levels - Info, Debug, Warn, Error
  4. Test edge cases - Not just happy path
  5. Profile performance - Don’t guess, measure
  6. Write unit tests - Prevent regressions
  7. Use version control - Commit working states

Next Steps