Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

README.md

Nucleation - JavaScript/TypeScript Documentation

Complete API reference and guide for using Nucleation in JavaScript and TypeScript (via WebAssembly).

Quick Start

npm install nucleation
import init, { SchematicWrapper } from "nucleation";

// Initialize WASM module
await init();

// Create schematic
const schematic = new SchematicWrapper();
schematic.set_block(0, 0, 0, "minecraft:stone");

// Save as litematic
const bytes = schematic.to_litematic();
// Download or save bytes...

Table of Contents

  1. Installation & Setup
  2. Core API
  3. Loading and Saving
  4. Block Operations
  5. Region Operations
  6. Block Entities
  7. SchematicBuilder
  8. Simulation
  9. TypedCircuitExecutor
  10. DefinitionRegion
  11. Procedural Building
  12. 3D Mesh Generation

Installation & Setup

Node.js / Bundlers

npm install nucleation
import init, { SchematicWrapper } from "nucleation";

// Auto-detects environment and loads WASM
await init();

const schematic = new SchematicWrapper();

Browser via CDN

<script type="module">
	import init, {
		SchematicWrapper,
	} from "https://cdn.jsdelivr.net/npm/nucleation@latest/nucleation-cdn-loader.js";

	await init(); // Automatically resolves WASM path
	const schematic = new SchematicWrapper();
</script>

Manual WASM Loading

import init, { SchematicWrapper } from "nucleation";

const wasmBytes = await fetch("/path/to/nucleation_bg.wasm").then((r) =>
	r.arrayBuffer()
);

await init(wasmBytes);

Core API

SchematicWrapper

Main class for working with schematics.

class SchematicWrapper {
	constructor(); // Creates empty schematic named "Default"

	// Loading/Saving
	from_data(bytes: Uint8Array): void;
	from_litematic(bytes: Uint8Array): void;
	from_schematic(bytes: Uint8Array): void;
	to_litematic(): Uint8Array;
	to_schematic(): Uint8Array;
	toSnapshot(): Uint8Array;
	fromSnapshot(bytes: Uint8Array): void;

	// Format Support
	static get_supported_import_formats(): string[];
	static get_supported_export_formats(): string[];
	static get_format_versions(format: string): string[];
	static get_default_format_version(format: string): string | undefined;
	
	save_as(format: string, version?: string): Uint8Array;

	// Block operations
	set_block(x: number, y: number, z: number, blockName: string): void;
	set_block_with_properties(
		x: number,
		y: number,
		z: number,
		blockName: string,
		properties: object
	): void;
	set_block_from_string(
		x: number,
		y: number,
		z: number,
		blockString: string
	): void;
	get_block(x: number, y: number, z: number): string | null;
	get_block_with_properties(
		x: number,
		y: number,
		z: number
	): BlockStateWrapper | null;

	// Block entities
	get_block_entity(x: number, y: number, z: number): object | null;
	get_all_block_entities(): Array<object>;

	// Region operations
	copy_region(
		sourceRegion: string,
		minX: number,
		minY: number,
		minZ: number,
		maxX: number,
		maxY: number,
		maxZ: number,
		targetX: number,
		targetY: number,
		targetZ: number,
		excludedBlocks: string[]
	): void;

	// Information
	get_dimensions(): [number, number, number];
	get_block_count(): number;
	get_volume(): number;
	get_region_names(): string[];
	debug_info(): string;
	print_schematic(): string;

	// Iteration
	blocks(): Array<{
		x: number;
		y: number;
		z: number;
		name: string;
		properties: object;
	}>;
	chunks(width: number, height: number, length: number): Array<any>;
	chunks_with_strategy(
		width: number,
		height: number,
		length: number,
		strategy: string,
		cx?: number,
		cy?: number,
		cz?: number
	): Array<any>;
	get_chunk_blocks(
		offsetX: number,
		offsetY: number,
		offsetZ: number,
		width: number,
		height: number,
		length: number
	): Array<any>;

	// Simulation (requires simulation feature)
	create_simulation_world(): MchprsWorldWrapper;
	create_simulation_world_with_options(
		options: SimulationOptionsWrapper
	): MchprsWorldWrapper;
}

BlockStateWrapper

Represents a block with properties.

class BlockStateWrapper {
	constructor(name: string);

	with_property(key: string, value: string): void; // Mutates in place
	name(): string;
	properties(): object;
}

Loading and Saving

Load from File

// Browser
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener("change", async (e) => {
	const file = e.target.files[0];
	const bytes = new Uint8Array(await file.arrayBuffer());

	const schematic = new SchematicWrapper();
	schematic.from_data(bytes); // Auto-detects format

	console.log(schematic.get_dimensions());
});

// Node.js
import { readFileSync } from "fs";

const bytes = new Uint8Array(readFileSync("input.litematic"));
const schematic = new SchematicWrapper();
schematic.from_litematic(bytes);

// Check supported formats
console.log(SchematicWrapper.get_supported_import_formats());
// ["litematic", "schematic", "mcstructure"]

Save to File

// Browser - Download
const bytes = schematic.to_litematic();
const blob = new Blob([bytes], { type: "application/octet-stream" });
const url = URL.createObjectURL(blob);

const a = document.createElement("a");
a.href = url;
a.download = "output.litematic";
a.click();

URL.revokeObjectURL(url);

// Node.js
import { writeFileSync } from "fs";

const bytes = schematic.to_litematic();
writeFileSync("output.litematic", bytes);

// Check export formats
console.log(SchematicWrapper.get_supported_export_formats());
// ["litematic", "schematic", "mcstructure"]

// Check versions
console.log(SchematicWrapper.get_format_versions("schematic"));
// ["v1", "v2", "v3"]

console.log(SchematicWrapper.get_default_format_version("schematic"));
// "v3"

// Save with specific format and version
const schemBytes = schematic.save_as("schematic", "v2");
writeFileSync("output.v2.schem", schemBytes);

Snapshot Format

The snapshot format is a fast binary serialization for caching and worker transfer. Much faster than standard formats but not compatible with Minecraft.

// Serialize to snapshot bytes
const snapshotData = schematic.toSnapshot();

// Load from snapshot (e.g., received from a Web Worker)
const schematic2 = new SchematicWrapper();
schematic2.fromSnapshot(snapshotData);

Block Operations

Setting Blocks

// Simple block
schematic.set_block(0, 0, 0, "minecraft:stone");

// Block with properties (object)
schematic.set_block_with_properties(0, 1, 0, "minecraft:lever", {
	facing: "east",
	powered: "false",
});

// Block from string (bracket notation)
schematic.set_block_from_string(
	1,
	1,
	0,
	"minecraft:redstone_wire[power=15,north=side,south=side]"
);

// Using BlockStateWrapper
const block = new BlockStateWrapper("minecraft:repeater");
block.with_property("facing", "east");
block.with_property("delay", "2");
// Note: BlockStateWrapper is mainly for reading, use set_block_with_properties for setting

Getting Blocks

// Get block name only
const blockName = schematic.get_block(0, 0, 0);
if (blockName) {
	console.log(`Block: ${blockName}`);
}

// Get block with properties
const blockState = schematic.get_block_with_properties(0, 1, 0);
if (blockState) {
	console.log(`Block: ${blockState.name()}`);
	console.log(`Properties:`, blockState.properties());
}

Iterating Blocks

// Get all blocks
const allBlocks = schematic.blocks();
for (const block of allBlocks) {
	console.log(`(${block.x}, ${block.y}, ${block.z}) = ${block.name}`);
	console.log(`Properties:`, block.properties);
}

// Filter non-air blocks
const nonAirBlocks = allBlocks.filter((b) => !b.name.includes("air"));

// Count block types
const blockCounts = new Map();
for (const block of allBlocks) {
	const count = blockCounts.get(block.name) || 0;
	blockCounts.set(block.name, count + 1);
}

Chunk Iteration

// Get chunks (bottom-up order)
const chunks = schematic.chunks(16, 16, 16);
for (const chunk of chunks) {
	console.log(
		`Chunk at (${chunk.offset_x}, ${chunk.offset_y}, ${chunk.offset_z})`
	);
	console.log(`Blocks:`, chunk.blocks);
}

// Get chunks with strategy
const strategies = [
	"distance_to_camera",
	"top_down",
	"bottom_up",
	"center_outward",
	"random",
];

const chunks = schematic.chunks_with_strategy(
	16,
	16,
	16,
	"distance_to_camera",
	0,
	100,
	0 // Camera position
);

// Get specific chunk
const chunkBlocks = schematic.get_chunk_blocks(0, 0, 0, 16, 16, 16);

Region Operations

Copying Regions

// Copy a region
schematic.copy_region(
	"Main", // Source region name
	0,
	0,
	0, // Min coordinates
	10,
	10,
	10, // Max coordinates
	20,
	0,
	0, // Target position
	["minecraft:air"] // Excluded blocks
);

Working with Multiple Regions

// Get all region names
const regions = schematic.get_region_names();
console.log(`Regions:`, regions);

// Get dimensions
const [width, height, depth] = schematic.get_dimensions();
console.log(`Size: ${width}x${height}x${depth}`);

// Get block/volume counts
console.log(`Blocks: ${schematic.get_block_count()}`);
console.log(`Volume: ${schematic.get_volume()}`);

Block Entities

Setting Block Entities

// Set block with entity using string notation
schematic.set_block_from_string(
	0,
	1,
	0,
	"minecraft:barrel[facing=up]{signal=13}"
);

// Note: Direct block entity manipulation is limited in WASM
// Use bracket notation with {nbt} for most cases

Getting Block Entities

// Get single block entity
const entity = schematic.get_block_entity(0, 1, 0);
if (entity) {
	console.log(`Entity:`, entity);
	// Entity is a plain JavaScript object with NBT data
}

// Get all block entities
const allEntities = schematic.get_all_block_entities();
for (const entity of allEntities) {
	console.log(
		`Entity at (${entity.x}, ${entity.y}, ${entity.z}):`,
		entity.data
	);
}

SchematicBuilder

Build schematics programmatically with ASCII art and compositional design.

See SchematicBuilder Guide for complete documentation.

Quick Example

import init, { SchematicBuilder } from "nucleation";
await init();

const circuit = SchematicBuilder.new()
	.from_template(
		`
    # Base layer
    ccc
    ccc
    
    # Logic layer
    ─→─
    │█│
  `
	)
	.build();

Compositional Design

// Build basic gates
const andGate = createAndGate();
const xorGate = createXorGate();

// Compose into larger circuit
const halfAdder = SchematicBuilder.new()
	.map_schematic("A", andGate)
	.map_schematic("X", xorGate)
	.layers([["AX"]])
	.build();

Simulation

Simulate redstone circuits in real-time.

Basic Simulation

import init, { SchematicWrapper } from "nucleation";
await init();

const schematic = new SchematicWrapper();
// Build circuit...
schematic.set_block_from_string(
	0,
	1,
	0,
	"minecraft:lever[facing=north,powered=false]"
);
schematic.set_block_from_string(5, 1, 0, "minecraft:redstone_lamp[lit=false]");
// ... add redstone wiring ...

// Create simulation world
const world = schematic.create_simulation_world();

// Toggle lever
world.on_use_block(0, 1, 0);

// Run simulation
world.tick(10);
world.flush();

// Check if lamp is lit
const isLit = world.is_lit(5, 1, 0);
console.log(`Lamp is lit: ${isLit}`);

Custom IO Simulation

import { SimulationOptionsWrapper } from "nucleation";

// Configure custom IO positions
const options = new SimulationOptionsWrapper();
options.addCustomIo(0, 1, 0); // Input position
options.addCustomIo(10, 1, 0); // Output position

const world = schematic.create_simulation_world_with_options(options);

// Inject custom signal strength (0-15)
world.setSignalStrength(0, 1, 0, 15); // Max power
world.tick(5);
world.flush();

// Read signal strength
const outputSignal = world.getSignalStrength(10, 1, 0);
console.log(`Output signal: ${outputSignal}`);

Batch Signal Operations

// Set multiple signals at once
const positions = [
	[0, 1, 0],
	[0, 1, 2],
	[0, 1, 4],
];
const strengths = [15, 0, 15];

for (let i = 0; i < positions.length; i++) {
	const [x, y, z] = positions[i];
	world.setSignalStrength(x, y, z, strengths[i]);
}

world.tick(10);
world.flush();

// Read multiple signals
const outputs = positions.map(([x, y, z]) => world.getSignalStrength(x, y, z));

TypedCircuitExecutor

High-level API for circuit simulation with typed inputs/outputs.

See TypedCircuitExecutor Guide for complete documentation.

Quick Example

import {
	TypedCircuitExecutor,
	IoType,
	LayoutFunction,
	Value,
} from "nucleation";

// Define IO mappings
const inputs = new Map([
	[
		"a",
		{
			io_type: IoType.Bool,
			layout: LayoutFunction.OneToOne,
			positions: [[0, 1, 0]],
		},
	],
	[
		"b",
		{
			io_type: IoType.Bool,
			layout: LayoutFunction.OneToOne,
			positions: [[0, 1, 2]],
		},
	],
]);

const outputs = new Map([
	[
		"result",
		{
			io_type: IoType.Bool,
			layout: LayoutFunction.OneToOne,
			positions: [[10, 1, 0]],
		},
	],
]);

// Create executor
const executor = new TypedCircuitExecutor(world, inputs, outputs);

// Execute with typed values
const inputValues = new Map([
	["a", Value.Bool(true)],
	["b", Value.Bool(true)],
]);

const result = executor.execute(inputValues, {
	mode: "fixed_ticks",
	ticks: 100,
});

// Get typed output
const output = result.outputs.get("result");
console.log(`Result: ${output}`); // Value.Bool(true)

TypeScript Types

// Block state
interface BlockState {
	name: string;
	properties: Record<string, string>;
}

// Block with position
interface PositionedBlock {
	x: number;
	y: number;
	z: number;
	name: string;
	properties: Record<string, string>;
}

// Chunk
interface Chunk {
	offset_x: number;
	offset_y: number;
	offset_z: number;
	blocks: PositionedBlock[];
}

// Execution mode
type ExecutionMode =
	| { mode: "fixed_ticks"; ticks: number }
	| { mode: "until_condition"; output: string; condition: any; timeout: number }
	| { mode: "until_stable"; stable_ticks: number; timeout: number }
	| { mode: "until_change"; timeout: number };

Examples

Download Schematic

function downloadSchematic(schematic: SchematicWrapper, filename: string) {
	const bytes = schematic.to_litematic();
	const blob = new Blob([bytes], { type: "application/octet-stream" });
	const url = URL.createObjectURL(blob);

	const a = document.createElement("a");
	a.href = url;
	a.download = filename;
	a.click();

	URL.revokeObjectURL(url);
}

Upload Schematic

async function uploadSchematic(file: File): Promise<SchematicWrapper> {
	const bytes = new Uint8Array(await file.arrayBuffer());
	const schematic = new SchematicWrapper();
	schematic.from_data(bytes);
	return schematic;
}

// Usage
const input = document.querySelector('input[type="file"]');
input.addEventListener("change", async (e) => {
	const schematic = await uploadSchematic(e.target.files[0]);
	console.log(schematic.get_dimensions());
});

Build and Test Circuit

async function buildAndTestCircuit() {
	await init();

	const schematic = new SchematicWrapper();

	// Build AND gate
	schematic.set_block(0, 0, 0, "minecraft:stone");
	schematic.set_block_from_string(
		0,
		1,
		0,
		"minecraft:lever[facing=north,powered=false]"
	);
	// ... build circuit ...

	// Test simulation
	const world = schematic.create_simulation_world();
	world.on_use_block(0, 1, 0); // Toggle input
	world.tick(10);
	world.flush();

	const output = world.is_lit(10, 1, 0);
	console.log(`Test passed: ${output === true}`);
}

DefinitionRegion

Advanced region manipulation for defining circuit IO areas.

See Circuit API Guide for complete documentation.

Creating Regions

import { DefinitionRegionWrapper, BlockPosition } from "nucleation";

// Create empty region
const region = new DefinitionRegionWrapper();

// Add bounding box
region.addBounds(new BlockPosition(0, 1, 0), new BlockPosition(7, 1, 0));

// Add single point
region.addPoint(10, 1, 0);

// Create from bounds directly
const region2 = DefinitionRegionWrapper.fromBounds(
	new BlockPosition(0, 0, 0),
	new BlockPosition(10, 10, 10)
);

Boolean Operations

const regionA = new DefinitionRegionWrapper();
regionA.addBounds(new BlockPosition(0, 0, 0), new BlockPosition(5, 0, 0));

const regionB = new DefinitionRegionWrapper();
regionB.addBounds(new BlockPosition(3, 0, 0), new BlockPosition(8, 0, 0));

// Mutating operations (modify in-place)
regionA.subtract(regionB); // Remove B's points from A
regionA.intersect(regionB); // Keep only common points
regionA.unionInto(regionB); // Add B's points to A

// Immutable operations (return new region)
const diff = regionA.subtracted(regionB);
const common = regionA.intersected(regionB);
const combined = regionA.union(regionB);

Geometric Transformations

const region = new DefinitionRegionWrapper();
region.addBounds(new BlockPosition(0, 0, 0), new BlockPosition(10, 10, 10));

// Move region
region.shift(100, 50, 200);

// Expand outward
region.expand(2, 2, 2);

// Contract inward
region.contract(1);

// Get bounds
const bounds = region.getBounds();
// { min: [x, y, z], max: [x, y, z] } or null

Connectivity Analysis

// Check if all points are connected (6-connectivity)
const isConnected = region.isContiguous();

// Count separate islands
const componentCount = region.connectedComponents();

Filtering by Block Properties

const schematic = new SchematicWrapper();
// ... add blocks ...

// Filter by block name
const lamps = region.filterByBlock(schematic, "redstone_lamp");

// Filter by properties
const litLamps = region.filterByProperties(schematic, { lit: "true" });

Position Iteration

// Get all positions (in add order)
const positions = region.positions(); // [[x,y,z], ...]

// Get positions in deterministic Y→X→Z order (for bit assignment)
const sortedPositions = region.positionsSorted();

Memory Management

// ⚠️ IMPORTANT: Free WASM objects when done
const region = new DefinitionRegionWrapper();
// ... use region ...
region.free(); // Required to prevent memory leaks

CircuitBuilder

Fluent API for creating TypedCircuitExecutor instances.

See Circuit API Guide for complete documentation.

Basic Usage

import {
	CircuitBuilderWrapper,
	DefinitionRegionWrapper,
	IoTypeWrapper,
	BlockPosition,
} from "nucleation";

const schematic = new SchematicWrapper();
// ... build your circuit ...

// Define IO regions
const inputRegion = new DefinitionRegionWrapper();
inputRegion.addBounds(new BlockPosition(0, 1, 0), new BlockPosition(7, 1, 0));

const outputRegion = new DefinitionRegionWrapper();
outputRegion.addBounds(
	new BlockPosition(0, 1, 20),
	new BlockPosition(7, 1, 20)
);

// Build executor with fluent API
const executor = new CircuitBuilderWrapper(schematic)
	.withInputAuto("data_in", IoTypeWrapper.unsignedInt(8), inputRegion)
	.withOutputAuto("data_out", IoTypeWrapper.unsignedInt(8), outputRegion)
	.withStateMode("stateful")
	.buildValidated();

// Clean up regions (executor clones them)
inputRegion.free();
outputRegion.free();

From Insign Annotations

// Create from sign annotations in schematic
const builder = CircuitBuilderWrapper.fromInsign(schematic);
const executor = builder.build();

Validation

const builder = new CircuitBuilderWrapper(schematic)
	.withInputAuto("a", IoTypeWrapper.unsignedInt(8), regionA)
	.withOutputAuto("out", IoTypeWrapper.unsignedInt(8), regionOut);

// Explicit validation (throws on error)
builder.validate();

// Or validate during build
const executor = builder.buildValidated();

State Modes

// Reset before each execute (default)
builder.withStateMode("stateless");

// Preserve state between executes
builder.withStateMode("stateful");

// Manual control (use tick/flush)
builder.withStateMode("manual");

Manual Tick Control

const executor = builder.withStateMode("manual").build();

// Set inputs individually
executor.setInput("a", ValueWrapper.fromU32(5));
executor.setInput("b", ValueWrapper.fromU32(3));
executor.flush();

// Tick manually
for (let i = 0; i < 10; i++) {
	executor.tick(1);
	executor.flush();

	const result = executor.readOutput("sum");
	console.log(`Tick ${i}: ${result.toJs()}`);
}

Layout Debugging

// See exactly which block maps to which bit
const layoutInfo = executor.getLayoutInfo();

console.log("Inputs:");
for (const [name, info] of Object.entries(layoutInfo.inputs)) {
	console.log(`  ${name}: ${info.ioType} (${info.bitCount} bits)`);
	info.positions.forEach((pos, bit) => {
		console.log(`    Bit ${bit}: [${pos.join(", ")}]`);
	});
}

Procedural Building

Generate structures procedurally using geometric shapes and brushes.

import { 
    ShapeWrapper, 
    BrushWrapper, 
    WasmBuildingTool, 
    SchematicWrapper 
} from "nucleation";

const schematic = new SchematicWrapper();

// Create a sphere shape
const sphere = ShapeWrapper.sphere(
    0, 0, 0, // Center (x, y, z)
    10.0     // Radius
);

// Create a gradient brush (Red -> Blue)
const brush = BrushWrapper.linear_gradient(
    0, 0, 0, 255, 0, 0,      // Start: Pos(0,0,0), Red(255,0,0)
    10, 0, 0, 0, 0, 255,     // End: Pos(10,0,0), Blue(0,0,255)
    1,                       // 1 = Oklab interpolation (smoother), 0 = RGB
    ["wool"]                 // Optional filter: only use wool blocks
);

// Apply brush to shape
WasmBuildingTool.fill(schematic, sphere, brush);

Simple Helpers

For simple tasks, you can use the direct methods on SchematicWrapper:

// Fill a cuboid region with a solid block
schematic.fillCuboid(
    0, 0, 0,      // Min [x, y, z]
    10, 5, 10,    // Max [x, y, z]
    "minecraft:red_concrete"
);

// Fill a sphere with a solid block
schematic.fillSphere(
    0, 0, 0,      // Center [x, y, z]
    10.0,         // Radius
    "minecraft:blue_wool"
);

Available Brushes

// Solid block
const solid = BrushWrapper.solid("minecraft:stone");

// Solid color (matches closest block)
const color = BrushWrapper.color(255, 128, 0, null); // Orange

// 4-Point Bilinear Gradient (Quad)
const bilinear = BrushWrapper.bilinear_gradient(
    0, 0, 0, 10, 0, 0, 0, 10, 0,  // Origin, U-end, V-end
    255, 0, 0,    // Origin Color (Red)
    0, 0, 255,    // U-end Color (Blue)
    0, 255, 0,    // V-end Color (Green)
    255, 255, 0,  // Opposite Color (Yellow)
    1,            // Oklab interpolation
    null          // No filter
);

// Point Cloud Gradient (Arbitrary points, IDW)
const points = BrushWrapper.point_gradient(
    // Positions [x1, y1, z1, x2, y2, z2...]
    [0, 0, 0,  10, 10, 10,  5, 5, 5],
    // Colors [r1, g1, b1, r2, g2, b2...]
    [255, 0, 0,  0, 0, 255,  0, 255, 0], 
    2.5,  // Falloff (power), default 2.0
    1,    // Oklab
    null
);

Palette Management

Use PaletteManager to get blocks for your UI dropdowns.

import { PaletteManager } from "nucleation";

// Get all wool blocks
const woolBlocks = PaletteManager.getWoolBlocks();

// Get concrete blocks
const concreteBlocks = PaletteManager.getConcreteBlocks();

// Get custom mix (e.g., all wool + obsidian)
const customPalette = PaletteManager.getPaletteByKeywords(["wool", "obsidian"]);

3D Mesh Generation

Generate 3D meshes from schematics using Minecraft resource packs.

Loading a Resource Pack

import { ResourcePackWrapper, MeshConfigWrapper } from 'nucleation';

// Load from bytes (e.g., fetched ZIP file)
const response = await fetch('resourcepack.zip');
const data = new Uint8Array(await response.arrayBuffer());
const pack = new ResourcePackWrapper(data);

console.log(`Blockstates: ${pack.blockstateCount}`);
console.log(`Models: ${pack.modelCount}`);
console.log(`Textures: ${pack.textureCount}`);

Generating Meshes

const config = new MeshConfigWrapper();
config.setCullHiddenFaces(true);
config.setAmbientOcclusion(true);
config.setAoIntensity(0.4);
config.setCullOccludedBlocks(true);
config.setGreedyMeshing(true);

// Generate GLB mesh
const result = schematic.toMesh(pack, config);
const glbData = result.glbData; // Uint8Array
console.log(`Vertices: ${result.vertexCount}, Triangles: ${result.triangleCount}`);

// Generate USDZ mesh
const usdzResult = schematic.toUsdz(pack, config);

// Generate raw mesh data
const raw = schematic.toRawMesh(pack, config);
const positions = raw.positionsFlat(); // Float32Array
const indices = raw.indices(); // Uint32Array

Per-Region and Per-Chunk Meshing

// Per region
const multi = schematic.meshByRegion(pack, config);
const names = multi.getRegionNames();
names.forEach(name => {
    const mesh = multi.getMesh(name);
    // use mesh.glbData
});

// Per chunk
const chunks = schematic.meshByChunk(pack, config);
const coords = chunks.getChunkCoordinates(); // [[x,y,z], ...]

// Custom chunk size
const chunks32 = schematic.meshByChunkSize(pack, config, 32);

Resource Pack Querying

const blockstates = pack.listBlockstates();
const models = pack.listModels();
const json = pack.getBlockstateJson("minecraft:stone");
const info = pack.getTextureInfo("minecraft:block/stone");
// { width, height, isAnimated, frameCount }

// Add custom entries
pack.addBlockstateJson("custom:block", jsonString);
pack.addModelJson("custom:block/my_block", modelJson);
pack.addTexture("custom:texture", 16, 16, rgbaBytes);

See Also