insign

Crates.ioinsign
lib.rsinsign
version0.1.1
created_at2025-09-02 04:36:51.574397+00
updated_at2025-09-02 07:03:11.697966+00
descriptionInsign: a tiny DSL for Minecraft build regions & metadata
homepage
repositoryhttps://github.com/Schem-at/Insign
max_upload_size
id1820612
size240,702
Harrison (Nano112)

documentation

README

Insign — a tiny DSL for Minecraft build regions & metadata

CI Security Crates.io Documentation License

Goal: author compact annotations on signs/books (or any text source) that compile into a deterministic regions + metadata structure you can ship with schematics and tools.

  • Regions = unions of axis-aligned boxes (AABBs) keyed by IDs like cpu.core
  • Metadata = namespaced key/values attached to regions (plus $global and wildcards like cpu.*)
  • Authoring constraints: terse on signs, multi-line friendly, stable & deterministic

This repository currently contains the spec and examples. Implementation comes next.


Why?

  • Portable context for builds: label sub-assemblies, bus lines, rooms—precisely and repeatably.
  • Machine-readable: consumers (renderers, validators, pipelines) can query regions and inherited metadata.
  • Sign-friendly: minimal punctuation, statement markers, multi-line allowed.

Library I/O (language-agnostic)

Input

An ordered array of tuples: ([sx, sy, sz], text).

[
  {
    "pos": [10, 64, 10],
    "text": "@rc([0,0,0],[3,2,1])\n#doc.label=\"Patch A\""
  },
  {
    "pos": [0, 64, 0],
    "text": "@cpu.core=ac([100,70,-20],[104,72,-18])\n#cpu.core:logic.clock_hz=4\n#cpu.*:power.budget=\"low\"\n#$global:io.bus_width=8"
  }
]
  • pos is the source block’s world coords (sign/lectern).
  • text is raw DSL; newlines allowed.
  • Order is used only to derive stable IDs for anonymous regions; it must not affect semantics.

Output (conceptual JSON)

{
  "$global": { "metadata": { "io.bus_width": 8 } },
  "cpu.*":   { "metadata": { "power.budget": "low" } },

  "__anon:0:0": {
    "bounding_boxes": [[[10,64,10],[13,66,11]]],
    "metadata": { "doc.label": "Patch A" }
  },

  "cpu.core": {
    "bounding_boxes": [[[100,70,-20],[104,72,-18]]],
    "metadata": { "logic.clock_hz": 4 }
  }
}

Notes

  • rc is relative to pos; ac is absolute.
  • Bounds are inclusive; each box is stored as a pair of vec3 corners, normalized per axis.
  • Anonymous regions appear only if they received metadata (recommended).

Authoring Syntax (sign-friendly)

  • Geometry starts with @
  • Metadata starts with #

A statement starts at @ or # and ends right before the next @/# (or end of text). Newlines are allowed inside a statement.

Geometry (@…)

Named regions (unified form)

@<region>=rc([x1,y1,z1],[x2,y2,z2])   // relative to this tuple’s pos
@<region>=ac([x1,y1,z1],[x2,y2,z2])   // absolute world coords
@<region>=<expr>                       // boolean expression over regions

Anonymous regions (no =; sign-local only)

@rc([x1,y1,z1],[x2,y2,z2])
@ac([x1,y1,z1],[x2,y2,z2])
@def(<expr>)

Booleans (Phase 0 / MVP)

<expr> := term { + term }*
term   := <region> | ( <expr> )
  • Operators: + union only in Phase 0.
  • Other ops (-, &, ^) are reserved for a later phase.

Current region .

  • Within a single tuple, the most recent geometry statement (named or anonymous).
  • No current region across tuples.

Metadata (#…)

Attach to current region (this tuple):

#key=<json>

Attach to an explicit target (dense):

#<target>:<key>=<json>

Where <target> is:

  • a region ID (foo or foo.bar)
  • a wildcard prefix (prefix.*)
  • $global

Values: strict JSON (string/number/bool/null/array/object). (No computed value functions in v0.1; reserved for future.)


Inheritance & Determinism

  • Read-time precedence per key: Exact region > longest matching wildcard(s) > $global.

  • Conflicts: different values for the same <named target, key> across tuples → compile error (identical duplicates allowed).

  • A named region is either:

    • Accumulator (one or more rc/ac append boxes), or
    • Defined (@<region>=<expr>). Mixing both modes is an error.
  • Anonymous region IDs derive from (tuple_index, statement_index)—never random UUIDs.

  • Deterministic output ordering is recommended: $global, then wildcards (lexicographic), then regions (lexicographic).


Examples

1) Anonymous region + inline metadata (relative)

@rc([0,64,0],
    [31,72,15])
#doc.label="Data Loop"
#logic.clock_hz=4

2) Named accumulators split across signs

@dataloop=rc([0,64,0],[31,72,15])
@dataloop.alu=rc([8,64,8],[22,70,14])
@dataloop.registers=rc([2,64,2],[12,69,6])+rc([14,64,2],[24,69,6])

#dataloop:doc.label="Data Loop"
#dataloop.registers:logic.word_size=8

3) Boolean union (Phase 0)

@core=dataloop.alu+dataloop.registers
#core:doc.note="ALU ∪ registers"

4) Absolute span + targeted metadata

@cpu.bus=ac([100,70,-20],[132,78,-5])
#cpu.bus:io.direction="east-west"

5) Wildcards & global metadata

#cpu.*:logic.clock_hz=4
#$global:io.bus_width=8

6) Multi-line statements are fine

@dataloop.registers=rc([2,64,2],
                       [12,69,6])
                    + rc([14,64,2],
                         [24,69,6])
#dataloop.registers:doc.note="two banks"

Formal Grammar (EBNF, v0.1)

Lexical

digit      = "0"…"9" ;
int        = ["-"], digit, { digit } ;
region-id  = 1*( ALNUM | "_" | "." ) ;      // [A-Za-z0-9_.]+
key        = region-id ;
vec3       = "[", int, ",", int, ",", int, "]" ;
box        = vec3, ",", vec3 ;

Program

input      = { stmt } ;
stmt       = geom | meta ;

Geometry

geom       = "@", ( named-geom | anon-geom ) ;

named-geom = region-id, "=", ( "rc(", box, ")"
                             | "ac(", box, ")"
                             | expr ) ;

anon-geom  = "rc(", box, ")"
           | "ac(", box, ")"
           | "def(", expr, ")" ;

expr       = term, { "+", term } ;          // Phase 0: union only
term       = region-id | "(", expr, ")" ;

Metadata

meta           = "#", ( targeted-meta | current-meta ) ;

targeted-meta  = meta-target, ":", key, "=", json ;
current-meta   = key, "=", json ;

meta-target    = "$global" | region-id | region-id, ".*" ;
json           = RFC 8259 JSON literal ;

Installation & Usage

Rust Library

Add to your Cargo.toml:

[dependencies]
insign-core = "0.1.1"

# For FFI bindings (Kotlin/JVM integration)
insign-ffi = "0.1.1"

# For WASM bindings (Web/Node.js)
insign-wasm = "0.1.1"

Basic usage:

use insign_core::compile;

let input = vec![
    ([10, 64, 10], "@rc([0,0,0],[3,2,1])\n#doc.label=\"Patch A\"".to_string()),
];

let result = compile(&input)?;
let json = serde_json::to_string_pretty(&result)?;
println!("{}", json);

CLI Tool

Install from crates.io:

cargo install insign-core --features=cli

Or download pre-built binaries from the GitHub Releases page.

echo '{"pos": [0,0,0], "text": "@rc([0,0,0],[1,1,1])\\n#test=1"}' | insign-cli --pretty

FFI (Kotlin/JVM)

Download the appropriate native library from GitHub Releases:

  • Linux: libinsign_ffi.so
  • macOS: libinsign_ffi.dylib
  • Windows: insign_ffi.dll
// Example Kotlin integration (requires JNA)
val library = Native.load("insign_ffi", InsignLibrary::class.java)
val json = "[{\"pos\":[0,0,0],\"text\":\"@rc([0,0,0],[1,1,1])\"}]"
val result = library.compile_json(json)
println(result)

WASM (Web/Node.js)

Node.js:

npm install @schem-at/insign-wasm
const { compile_json } = require('@schem-at/insign-wasm');

const input = JSON.stringify([
  { pos: [0,0,0], text: "@rc([0,0,0],[1,1,1])\n#test=1" }
]);

const result = compile_json(input);
console.log(JSON.parse(result));

Browser:

<script type="module">
import init, { compile_json } from './pkg/insign.js';

async function run() {
  await init();
  
  const input = JSON.stringify([
    { pos: [0,0,0], text: "@rc([0,0,0],[1,1,1])\n#test=1" }
  ]);
  
  const result = compile_json(input);
  console.log(JSON.parse(result));
}

run();
</script>

Development

Building from Source

# Clone the repository
git clone https://github.com/Schem-at/Insign.git
cd Insign

# Build all packages
cargo build --all --release

# Run tests
cargo test --all

# Build FFI library
cargo build -p insign-ffi --release

# Build WASM package
cd crates/insign-wasm
wasm-pack build --release --target nodejs --out-dir pkg --out-name insign

Parity Testing

To verify that FFI and WASM produce identical outputs:

./tools/scripts/parity-simple.sh

License

MIT (see LICENSE in this repository).

Commit count: 22

cargo fmt