Repository
lib-script
The scripting language and engine behind Kinogaki Studio's Wrangle nodes: Studio's own version of VEX.
- GitHub
- kinogaki/lib-script (private)
- Folder
libs/lib-script/- Crates
- 7
- Rust lines
- 17,475 in src, 2,469 in tests
Crates
| Crate | What it is | Files | Lines | Test lines |
|---|---|---|---|---|
kinogaki-script-bench | Benchmarks on the test host, 1M elements: cargo run --release -p kinogaki-script-bench. | 1 | 95 | 0 |
kinogaki-script-exec | lib-script's engine: a column (batch) interpreter in safe Rust. | 12 | 3,250 | 2,352 |
kinogaki-script-host | The boundary between lib-script and a host. | 9 | 1,275 | 0 |
kinogaki-script-ir | lib-script's column IR: typed SSA values (vectors as groups of scalar values) in structured regions; lowering from the checked program; uniform/varying analysis; optimisation; a verifier; and the fault table that maps instructions back to source spans. | 14 | 3,486 | 0 |
kinogaki-script-lib | lib-script's function library. | 13 | 2,455 | 19 |
kinogaki-script-syntax | lib-script's syntax: an indentation-aware lexer, a recovering parser and a syntax tree whose every node keeps the exact span of its text. | 10 | 2,147 | 98 |
kinogaki-script-types | lib-script's front end after parsing: types, the host schema a context offers, the library catalog's signatures, the checker that builds the typed program, and completion and hover for the editor. | 15 | 4,767 | 0 |
README
lib-script
The scripting language and engine behind Kinogaki Studio's Wrangle nodes: Studio's own version of VEX. Scripts are Python-like with static types (see docs/LANGUAGE.md), run per point, primitive, vertex, edge, once per geometry or over numbers, and run in parallel. The engine is a column (batch) interpreter in safe Rust: each instruction runs over a chunk of 1024 elements as one tight loop. The function reference is docs/FUNCTIONS.md, generated from the signature table.
The core knows no geometry. A context (Mesh first, later Volume, SDF, splats, CAD) implements the host trait ScriptContext and supplies the names, the columns and the context functions.
| Crate | Role |
|---|---|
kinogaki-script-syntax (crates/syntax) | Indentation-aware lexer, recovering parser (one diagnostic per bad line, the rest still parses), syntax tree with exact spans, highlighting classes |
kinogaki-script-types (crates/types) | Types, the host Schema, the library Catalog of signatures, the checker (inference from first assignment, overloads, tuples taking the expected vector type, definite assignment, Python-habit messages) building the typed program (hir), and complete / hover |
kinogaki-script-host (crates/host) | The boundary: ScriptContext, ScriptOutput, HostCall, lanes, list storage, the edit queue, and table::TableHost, an in-memory test host |
kinogaki-script-ir (crates/ir) | The column IR: typed SSA values (vectors are groups of scalar values) in structured regions; lowering with inlining; uniform/varying analysis; folding (parameters too, when specialized), CSE, loop-value and dead-code removal; the verifier; operation semantics shared by every evaluator |
kinogaki-script-lib (crates/lib) | The function library: signature rows with a scalar reference and a column form each; ramps in FloatRamp's encoding |
kinogaki-script-exec (crates/exec) | The engine: register allocation, the chunk interpreter (masks, all-on/all-off fast paths, real branches on uniform conditions), parallel chunks on lib-parallel, lowest-element faults, cancellation, the compile cache; and the scalar reference interpreter the tests compare against |
kinogaki-script-bench (crates/bench) | Benchmarks at 1M elements on the test host |
Using it
kinogaki_script_exec::{check, complete, hover} serve the code editor from one check of the text.
The host trait
A context implements ScriptContext (crates/host/src/context.rs):
domains(): its Run Over choices (label and element name);schema(): what the chosen one offers — the element and its typed fields and groups (createlets scripts add attributes,creatablelimits their types to what the host stores),geoas a read-only detail, the inputs' collections and detail values, and context functions (signature, owner — global, element,geoor input method — pure or a queued edit).len(),active(first, mask)(a group restriction),load(slot, comp, first, out)for the element's fields and groups,detail(at, comp),count(collection),gather(collection, field, comp, indices, out)(indices already bounds-checked).call(func, &mut HostCall): a context function's column kernel over a chunk (or once, for uniform arguments); list results are pushed per lane; an error names its lane and becomes a fault.
Writes go through ScriptOutput::parts(chunk): one disjoint part per chunk, so chunks store in parallel; on a failed run the host discards the output. Edits (EditKind::Call for edit functions, EditKind::Set for geo.points[i].F = v) come back in element order.
Checks
The tests cover each stage, a conformance corpus with expected values, faults (lowest element, no partial output), bit-identical results at 1, 2 and 16 workers, every library function's column form against its scalar reference, and a fuzzer of random well-typed programs compared with the scalar reference.
Benchmarks
cargo run --release -p kinogaki-script-bench on the test host, 1M points, M4 Max (16 cores), best of 9 whole runs (output columns made, every chunk run, results stored). Measured 2026-10-27 with the machine shared by other work (load average about 27), so whole-run times are pessimistic:
| Case | Target | Whole run | One thread |
|---|---|---|---|
7-op arithmetic (x = pt.P.x * 4; pt.P.y += (x - x*x*x*(1/6)) * 0.1) | ≤ 3 ms | 1.6–2.0 ms | 3.0–3.6 ms |
pt.P += noise(pt.P) (vector Perlin, three channels) | ≤ 8 ms | 6.0–7.1 ms (9.0 at worst load) | 44 ms |
| empty script | ≤ 2 ms | < 0.01 ms | |
| check + lower 53 lines | ≤ 5 ms | 0.5–1.0 ms |
Siblings
It reaches sibling checkouts as the Kinogaki Studio tree has them under libs/: ../lib-math (vectors and the deterministic elementary functions) and ../lib-parallel (scoped parallel chunks). It has no other dependencies.
Its documents
The repository's architecture document as written there (code blocks and links left out), and the opening of each other document.
Function reference (libs/lib-script/docs/FUNCTIONS.md)
Generated from lib-script's signature table (cargo test -p kinogaki-script-lib checks it is current; LIB_SCRIPT_WRITE_DOCS=1 rewrites it). Forms that differ only in result type are chosen by where the result goes: v: vec3 = noise(p) and pt.P + noise(p) take the vec3 form; without a hint the first form listed wins. The rules are under "Overload resolution" in LANGUAGE.md.
lib-script language reference (libs/lib-script/docs/LANGUAGE.md)
lib-script is the language of Kinogaki Studio's Wrangle nodes. It reads like Python: blocks by indentation, # comments, def, if/elif/else, for, while. Unlike Python, every name has one static type, inferred from its first assignment, and the script is checked before it runs. The function names and their meanings follow Houdini's VEX where VEX has them.
