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
depends on (an edge implied by others shows when you point at a box)used by tests alone

Crates

CrateWhat it isFilesLinesTest lines
kinogaki-script-benchBenchmarks on the test host, 1M elements: cargo run --release -p kinogaki-script-bench.1950
kinogaki-script-execlib-script's engine: a column (batch) interpreter in safe Rust.123,2502,352
kinogaki-script-hostThe boundary between lib-script and a host.91,2750
kinogaki-script-irlib-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.143,4860
kinogaki-script-liblib-script's function library.132,45519
kinogaki-script-syntaxlib-script's syntax: an indentation-aware lexer, a recovering parser and a syntax tree whose every node keeps the exact span of its text.102,14798
kinogaki-script-typeslib-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.154,7670

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.

CrateRole
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 (create lets scripts add attributes, creatable limits their types to what the host stores), geo as a read-only detail, the inputs' collections and detail values, and context functions (signature, owner — global, element, geo or 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:

CaseTargetWhole runOne thread
7-op arithmetic (x = pt.P.x * 4; pt.P.y += (x - x*x*x*(1/6)) * 0.1)≤ 3 ms1.6–2.0 ms3.0–3.6 ms
pt.P += noise(pt.P) (vector Perlin, three channels)≤ 8 ms6.0–7.1 ms (9.0 at worst load)44 ms
empty script≤ 2 ms< 0.01 ms
check + lower 53 lines≤ 5 ms0.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.