Skip to content

StasisCo/lev

Repository files navigation

lev

lightweight scripting language for jvm. zero deps, single jar, plug anywhere. designed for end users who don't program and devs who do.

build

./gradlew build

jar at build/libs/lev-1.0.0.jar. run standalone:

java -jar build/libs/lev-1.0.0.jar script.l

dependency

uses JitPack. add to your project:

gradle (build.gradle)

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.stasisco:lev:1.0.0'
}

gradle (build.gradle.kts)

repositories {
    maven("https://jitpack.io")
}

dependencies {
    implementation("com.github.stasisco:lev:1.0.0")
}

maven (pom.xml)

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.stasisco</groupId>
    <artifactId>lev</artifactId>
    <version>1.0.0</version>
</dependency>

syntax

-- comments use double dash
-- no let needed, no semicolons

name = "lev"
version = 2
items = [1, 2, 3]
config = { "key": "value", "n": 42 }

-- math namespace
math.round(3.7)
math.sin(math.pi / 2)
math.rand()
math.clamp(value, 0, 100)
math.lerp(a, b, 0.5)

-- functions (fn or function)
fn add(a, b) { return a + b }
function multiply(a, b) { return a * b }

-- single-line if (colon syntax) - great for simple checks
if health < 20 : print("low!") end
if armor > 10 : print("tanky") : else print("squishy") end

-- block style
if x > 5 {
    print("big")
} else {
    print("small")
}

-- loops
while x > 0 { x -= 1 }
for item in items { print(item) }
for i in 0..10 { print(i) }

-- lambdas and pipes
items.map((x) -> x * 2)
items.filter((x) -> x > 2)
"hello" | print

-- logical operators (word-style)
if not dead and health > 0 : print("alive") end

-- string/array methods
"hello".upper()
"hello world".split(" ")
items.push(4)
items.join(", ")
items.sort().reverse()

add (imports)

bring in managers/modules without touching hooks directly:

add rotationManager
add interactionManager as interact
add swapManager as swap

-- then use them
rotman.rotateTo(target.getAABB())
interact.attack(target)
swap.hotbar(0)

the host resolves add names to real objects at runtime.

hooks

mode-aware events. host fires, scripts handle:

-- fires only in integrated mode
hook render:integrated() {
    renderer.text(10, 10, "FPS: " + str(getFps()))
}

-- fires only standalone
hook render:standalone() {
    print("fps: " + str(fps))
}

-- fires always
hook tick() {
    if player.health < 10 : print("danger!") end
}

-- receives params from host
hook keypress(key, mods) {
    if key == "r" : toggle() end
}

embedding (java)

var engine = new LevEngine();
engine.setMode("integrated");

// expose functions - scripts call these directly
engine.expose("getFps", args -> (double) mc.getFps());
engine.expose("chat", args -> { mc.player.chat((String) args.get(0)); return null; });

// expose modules (add resolves to these)
engine.exposeModule("rotationManager", Map.of(
    "rotateTo", args -> { rotate((AABB) args.get(0)); return null; },
    "reset", args -> { resetRotation(); return null; }
));

engine.exposeModule("renderer", Map.of(
    "text", args -> { drawText(...); return null; },
    "rect", args -> { drawRect(...); return null; }
));

// load user scripts
engine.runFile("scripts/hud.l");
engine.runFile("scripts/killaura.l");

// game loops
engine.fireHook("render");      // render loop
engine.fireHook("tick");        // game tick
engine.fireHook("keypress", key, mods);  // events

modes

  • standalone - outside any client (testing)
  • integrated - inside client with bridge
  • module - toggleable module
  • custom - whatever you want

set with engine.setMode("mode") from java.

vscode

extension included in vscode-lev/. provides:

  • syntax highlighting (-- comments, keywords, hooks, math)
  • intellisense dropdown (builtins, math.*, methods, user symbols, modules)
  • signature help
  • hover docs
  • document outline
  • snippets (fn, hook, add, if, module scaffold)

install: copy vscode-lev/ to ~/.vscode/extensions/lev-lang-0.1.0/

file extension

.l

features

  • no let/var needed (bare assignment declares)
  • fn or function keywords
  • -- comments (// also works)
  • single-line if/else with colon syntax
  • add module as alias imports
  • math.* namespace (round, sin, cos, lerp, clamp, etc)
  • not, and, or word operators
  • closures, lambdas, higher-order functions
  • range expressions (0..10)
  • pipe operator
  • compound assignment (+=, -=, *=, /=)
  • built-in string/array/map methods
  • mode-filtered hook system
  • native bridge for host interop
  • zero dependencies
  • ~58kb jar

About

lightweight scripting language for jvm. zero deps, hooks, native bridge. made for minecraft client scripting.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors