Skip to main content

Introduction

LiquidBounce’s scripting system allows you to extend the client at runtime using various programming languages powered by GraalVM Polyglot. You can create custom modules, commands, and game logic without modifying the client’s source code.

Supported Languages

LiquidBounce supports multiple scripting languages through GraalVM:
  • JavaScript (Recommended) - Full ECMAScript 2023 support with Nashorn compatibility
  • Python - Via GraalPython
  • Any other language supported by GraalVM
JavaScript is the most tested and recommended language for scripting. All examples in this documentation use JavaScript.

Script Directory

Scripts are loaded from the scripts/ directory in your LiquidBounce folder:
LiquidBounce/
├── scripts/
│   ├── MyScript.js
│   ├── AnotherScript.js
│   └── MyProject/
│       └── main.js

Project Structure

For complex scripts with multiple files, create a directory with a main.js (or main.py) file:
  • Single file: scripts/MyScript.js
  • Multi-file project: scripts/MyProject/main.js
The ScriptManager will automatically detect and load the main file from directories.

Creating Your First Script

Create a file called HelloWorld.js in your scripts directory:
HelloWorld.js
registerScript({
    name: "HelloWorld",
    version: "1.0.0",
    authors: ["YourName"]
});

Client.displayChatMessage("Hello from LiquidBounce scripting!");

Script Registration

Every script must call registerScript() with the following properties:
  • name (string) - The script’s display name
  • version (string) - The script version
  • authors (string or array) - Script author(s)
Scripts that don’t call registerScript() will fail to load.

Loading Scripts

In-Game Commands

Use the following commands to manage scripts:
.script load <file>      - Load a specific script
.script unload <name>    - Unload a script
.script reload          - Reload all scripts
.script list            - List all loaded scripts

Automatic Loading

All scripts in the scripts/ directory are automatically loaded when LiquidBounce starts.

Script Lifecycle

Scripts have several lifecycle hooks you can use:
registerScript({
    name: "LifecycleDemo",
    version: "1.0.0",
    authors: ["YourName"]
});

// Called when the script is loaded
on("load", () => {
    Client.displayChatMessage("Script loaded!");
});

// Called when the script is enabled
on("enable", () => {
    Client.displayChatMessage("Script enabled!");
});

// Called when the script is disabled
on("disable", () => {
    Client.displayChatMessage("Script disabled!");
});

Accessing the Minecraft Client

The mc global variable provides direct access to the Minecraft client:
// Get the player
const player = mc.player;

// Get the world
const world = mc.level;

// Check if in-game
if (player !== null) {
    const health = player.getHealth();
    Client.displayChatMessage("Health: " + health);
}

Using the Client API

The Client object provides access to LiquidBounce’s features:
// Module Manager
const moduleManager = Client.moduleManager;
const killAura = moduleManager.getModule("KillAura");
killAura.enabled = true;

// Command Manager
const commandManager = Client.commandManager;

// Event Manager
const eventManager = Client.eventManager;

// Config System
const configSystem = Client.configSystem;

CommonJS Support (JavaScript)

JavaScript scripts support CommonJS modules:
utils.js
module.exports = {
    formatMessage: function(msg) {
        return "[MyScript] " + msg;
    }
};
main.js
const utils = require('./utils.js');

registerScript({
    name: "ModuleExample",
    version: "1.0.0",
    authors: ["YourName"]
});

Client.displayChatMessage(utils.formatMessage("Hello!"));

Local Storage

Scripts can store data using the localStorage object:
// Store data
localStorage["myKey"] = "myValue";
localStorage["counter"] = 0;

// Retrieve data
const value = localStorage["myKey"];

// Data persists across all scripts during the session
Local storage is cleared when all scripts are unloaded. Use the config system for persistent data.

Error Handling

Always wrap potentially failing code in try-catch blocks:
try {
    const player = mc.player;
    if (player === null) {
        throw new Error("Player is null");
    }
    // Your code here
} catch (error) {
    Client.displayChatMessage("Error: " + error.message);
}

Best Practices

  1. Always check for null - mc.player and mc.level can be null when not in-game
  2. Use descriptive names - Name your scripts, modules, and variables clearly
  3. Handle errors gracefully - Use try-catch to prevent script crashes
  4. Clean up resources - Use the disable hook to clean up event handlers
  5. Test thoroughly - Test scripts in different scenarios before sharing

Next Steps

Build docs developers (and LLMs) love