Typescript definition for minecraft and LiquidBounce
-
Following
repo
meansdemo
https://github.com/commandblock2/minecraft-LBNG-types.
minecraft-LBNG-types
DISCLAIMER: Use this at your own risk!!! This is an unofficial project not endorsed by Mojang or fabric developers. This repo does NOT
- contains any generated minecraft type definitions by itself
- redistribute the game itself
- guarentee the correctness of the generated definition
This repo contains
- instruction and scripts for creating typescript definitions
- for Minecraft (with mods*)
- for LiquidBounce NextGen
- for everything inside of the jvm
- typescript definitions for embedded context of LiquidBounce NextGen scriptAPI
- a set of manually maintained patches to make the script api work properly
- a set of examples LiquidBounce NextGen script using typescript
- a compiler script that will compile all the .ts files into .js files that could run in graaljs (LiquidBounce NextGen runtime) with watch mode
- some prompt files to use on LLMs, specifically for claude + continue.dev vscode extension, at .continue/prompts.
Note: the mods are only limited to those presented at the development environment of LiquidBounce NextGen.
When writing your script in typescript, expect inconsistencies with script API in js, but please report them to this repo if you can
Instruction (subject to change)
Adjust the order flexibly to your needs.
Generating the typescript definitions
-
Setup development environment for Liquidbounce NextGen
-
Clone LBNG, run
git checkout 451cb31e9bf093fe07f9b28202bc2471921ea13d
(for version 0.29.0 release) and launch with gradle./gradlew runClient
without intellij idea(recommened because of the sheer amount of memory it takes to generate the definition). -
Place the
LBNG-script/ts-defgen.js
in your script folder for LiquidBounce -
Build or download the latest released ts-generator jar from github, place it in your script folder as well.
-
Do a
.script reload
in your client, this should load thets-defgen.js
-
Run the
.ts-defgen
command -
See messages from chat and wait for around a few minute or more or less depending on your setup, this may take a while and also nearly 7GB of additional RAM (other than your intellij idea plus the what Minecraft needs in it's original state, causes OOM for me a lot of times xD).
Now you can find a
types-gen
folder in your script folder, this contains the generated typescript definitions.. ├── ts-defgen.js ├── ts-generator-1.1.1.jar └── types-gen └── minecraft-yarn-definitions ├── package.json ├── tsconfig.json └── types ├── ai ├── com ├── _COROUTINE ├── de ├── io ├── it ├── java ├── javax ├── jdk ├── joptsimple ├── kotlin ├── kotlinx ├── net ├── okhttp3 ├── okio ├── org ├── oshi └── sun ├── ... other scripts.js
Writing scripts with TypeScript Support
- Run
npm install
in this directory. - copy the generated folder
types-gen
togenerated-modules
folder in the root of your project. - Run the script
apply-patch
withnpm run apply-patches
- Run
npm install file:./generated-modules/types-gen/minecraft-yarn-definitions/ --no-save
, no-save for now, not sure if I should do this. - Open the
template.ts
file and try start writing your script, you should see TypeScript type hints for all the classes that are available. vscode will automatically generate working imports, but you should not touch the import statement with@embedded
namespace. - Run the script
compile
with npm like step 4 ornpm run watch
- Corresponding javascript file is generated in the
dist
directory, you can link this dist directory to your scripts directory in LB.
Contribution and TODOs
If you know how to better organize this project (architecture), please feel free to submit a PR.
If you find errors on generated definitions about Minecraft classes or LiquidBounce classes, please file your tick at ts-generator.
If you find a un-intended behavior in the
ts-defgen.js
, compile script or manually maintained definitions(TODO), please file an issue here.License
This project is licensed under the GNU General Public license, see LICENSE for more information.
-
Update: now the script will also print the embedded context made available by the script api
// Import required Java classes // type: array /** @type any[]*/ var globalEntries = Object.entries(this); const System = Java.type("java.lang.System"); const URLClassLoader = Java.type("java.net.URLClassLoader"); const File = Java.type("java.io.File"); const URL = Java.type("java.net.URL"); const Thread = Java.type("java.lang.Thread"); const Paths = Java.type("java.nio.file.Paths"); const Map = Java.type("java.util.HashMap"); const ArrayList = Java.type("java.util.ArrayList"); const JvmClassMappingKt = Java.type("kotlin.jvm.JvmClassMappingKt"); const Class = Java.type("java.lang.Class"); // Function to create a URLClassLoader from a JAR path function createClassLoaderFromJar(jarPath) { try { // Create File object for the JAR const jarFile = new File(jarPath); // Convert File to URL const jarUrl = jarFile.toURI().toURL(); // Create URLClassLoader with the system class loader as parent return new URLClassLoader( [jarUrl], Thread.currentThread().getContextClassLoader() ); } catch (e) { console.error("Error creating ClassLoader:", e); throw e; } } // Function to load a class from a given ClassLoader function loadClassFromJar(classLoader, className) { try { return classLoader.loadClass(className); } catch (e) { console.error(`Error loading class ${className}:`, e); throw e; } } const script = registerScript({ name: "for-repl", version: "1.0.0", authors: ["commandblock2"], }); script.registerModule( { name: "for-repl", category: "Client", description: "Sausage", settings: { path: Setting.text({ name: "Path", default: "/mnt/old-linux/home/commandblock2/git_repo/MultiMC5/build/instances/LBNG-Production/minecraft/LiquidBounce/scripts", }), packageName: Setting.text({ name: "NPMPackageName", default: "minecraft-yarn-definitions", }), }, }, (mod) => { mod.on("enable", (event) => { const loader = createClassLoaderFromJar( mod.settings.path.value + "/ts-generator-1.0.0.jar" ); const NPMGen = loadClassFromJar( loader, "me.commandblock2.tsGenerator.NPMPackageGenerator" ); const TsGen = loadClassFromJar( loader, "me.ntrrgc.tsGenerator.TypeScriptGenerator" ); const VoidType = loadClassFromJar( loader, "me.ntrrgc.tsGenerator.VoidType" ); const NULL = VoidType.getEnumConstants()[0]; const javaClasses = globalEntries .filter((entry) => entry[1] != undefined) .map((entry) => (entry[1] instanceof Class ? entry[1] : entry[1].class)) .filter((entry) => entry != undefined); const kotlinClasses = javaClasses.map((entry) => JvmClassMappingKt.getKotlinClass(entry) ); const classes = new ArrayList(kotlinClasses); try { const generated = new TsGen( classes, new Map(), new ArrayList(), new ArrayList(), "number", NULL ); const npmPack = new NPMGen(generated, mod.settings.packageName.value); npmPack.writePackageTo( Paths.get(mod.settings.path.value + "/types-gen") ); const embeddedDefinition = ` // imports ${javaClasses .map((clazz) => { return `import { ${clazz.simpleName} } from "@${mod.settings.packageName.value}/types/${clazz.name.replaceAll(".", "/")}";`; }) .join("\n")} // definitions for objects ${globalEntries .filter((entry) => entry[1] != undefined) .filter((entry) => !(entry[1] instanceof Class)) .filter((entry) => entry[1].class != undefined) .map((entry) => `export var ${entry[0]}: ${entry[1].class.simpleName};`) .join("\n\n")} `; console.log(embeddedDefinition) } catch (e) { e.printStackTrace(); console.error(e); throw e; } // ReflectionUtil.invokeMethod(mc.player, "getName") // event.context.drawGuiTexture(RenderLayer.getGuiTextured, CLOSE_TEXTURE, 0, 0, 16, 16, -1); }); } );
-
Update: subsequent updates will be available on https://github.com/commandblock2/minecraft-LBNG-types
and the generated script was reverted to a state where it was not as readable as the following example (for correctness) but still largely remained the same.
Now it can kinda generate a working script, but the ts file has a few squiggles.
template.ts
// imports import { Setting, Vec3i, Vec3d, MathHelper, BlockPos, Hand, RotationAxis, mc, Client, RotationUtil, ItemUtil, NetworkUtil, InteractionUtil, BlockUtil, MovementUtil, ReflectionUtil, ParameterValidator, UnsafeThread, registerScript } from "@embedded"; import { ScriptModule } from "@minecraft-yarn-definitions/types/net/ccbluex/liquidbounce/script/bindings/features/ScriptModule"; import { Matrix2d } from "@minecraft-yarn-definitions/types/org/joml/Matrix2d"; const script = registerScript.apply({ name: "template", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ // @ts-ignore name: "example-from-template", // @ts-ignore description: "Ths is an example module generated in ts", // @ts-ignore category: "Client" }, (mod: ScriptModule) => { mod.on("enable", () => { Client.displayChatMessage(`${mc.player}`) Client.displayChatMessage(`${new Vec3i(1, 2, 3)}`) Client.displayChatMessage(`${new Matrix2d(1.2, 1.3, 1.4, 15)}`) Client.displayChatMessage("enabled") }) mod.on("disable", () => Client.displayChatMessage("disabled")) })
compiled template.js
function __require(path) { if (path.startsWith("@embedded")) { return { _embedded: globalThis } } if (path.startsWith("@minecraft-yarn-definitions/types/")) { return { [path.substring(path.lastIndexOf("/") + 1)]: Java.type(path .replaceAll("@minecraft-yarn-definitions/types/", "") .replaceAll("/", ".") ) } } return require(path); } var exports = {} "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const { _embedded } = __require("@embedded"); const { Matrix2d } = __require("@minecraft-yarn-definitions/types/org/joml/Matrix2d"); const script = _embedded.registerScript.apply({ name: "template", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ // @ts-ignore name: "example-from-template", // @ts-ignore description: "Ths is an example module generated in ts", // @ts-ignore category: "Client" }, (mod) => { mod.on("enable", () => { _embedded.Client.displayChatMessage(`${_embedded.mc.player}`); _embedded.Client.displayChatMessage(`${new Vec3i(1, 2, 3)}`); _embedded.Client.displayChatMessage(`${new Matrix2d(1.2, 1.3, 1.4, 15)}`); _embedded.Client.displayChatMessage("enabled"); }); mod.on("disable", () => _embedded.Client.displayChatMessage("disabled")); });
-
Update for LiquidBounce v0.29.0:
What's new:- refined disclaimer in README.md
localStorage
in definition (no java.utils class definition yet)multiChoose
in manually maintained patch