Repository navigation
logic types
The decoupling hub between the logic layer and Blockbench. Zero dependencies — Node-testable.
export type Vec3 = [number, number, number];export type CubeFaceDirection = 'north' | 'south' | 'east' | 'west' | 'up' | 'down';A source texture extracted from a .bbmodel / the current project, imported into the new workspace and
applied to the matching faces. key is a unique id inside the source model (the .bbmodel texture id,
or the current project's texture UUID); CubeSpec face texture references use this key, which the
assembly layer maps to the imported Texture.
export interface SourceTexture {
key: string;
name: string;
source: string; // bitmap data: base64 data URL or desktop file path
width: number;
height: number;
}Face UV description (passed through to the Blockbench CubeFace).
export interface FaceSpec {
uv?: [number, number, number, number];
rotation?: number;
texture?: string; // source texture key (see SourceTexture); resolved by the assembly layer
}A mesh-group face: vertex ids + UV + the source texture key. uv is passed straight through from the
raw .bbmodel structure (per-vertex UV, array or object) and handed back to Blockbench unchanged.
export interface MeshFaceSpec {
vertices: string[]; // vertex ids forming the face (counter-clockwise)
uv?: number[] | Record<string, any>; // per-vertex UV (passthrough, unmodified)
rotation?: number;
texture?: string; // source texture key (see SourceTexture)
}A platform-independent cube description mirroring Blockbench's ICubeOptions. from/to are the two
opposite corners (px); rotation is the 3-axis rotation about origin (degrees).
export interface CubeSpec {
name?: string;
from: Vec3;
to: Vec3;
rotation?: Vec3;
origin?: Vec3;
faces?: Partial<Record<CubeFaceDirection, FaceSpec>>;
}A mesh-group element (.bbmodel type: 'mesh'): vertex id → position, face id → face.
export interface MeshSpec {
name?: string;
vertices: Record<string, Vec3>;
faces: Record<string, MeshFaceSpec>;
origin?: Vec3;
rotation?: Vec3;
}A part parsed from a .bbmodel / the current project. Normalization contract: bottom face y = 0, track
lateral centerline x = 0. cubes build the track shapes; meshes only the workspace base groups.
export interface PartModel {
cubes: CubeSpec[];
meshes?: MeshSpec[]; // mesh elements (type='mesh'); present ⇔ part contains mesh groups
hasMesh?: boolean; // decides free-model workspace
bbox: { min: Vec3; max: Vec3 }; // normalized bounding box (cubes + mesh vertices)
xMid: number; // lateral centerline x (≈0 after normalization)
textureSize?: [number, number]; // texture resolution [w, h] (px). Must match across all 3 parts
textures?: SourceTexture[]; // all source textures referenced by the part
}Optional portal configuration; the two textures are independently optional. trackTexture (portal_track)
textures the teleport track/tie (default: the parts' own textures); mipTexture (portal_track_mip)
generates the two overlay cubes teleport_left / teleport_right wrapping each half of the ties
(excluding the rails) (default: none). Structure follows Create's original teleport.json.
export interface PortalConfig {
trackTexture?: string; // portal_track source key (prefixed, e.g. 'P/track')
mipTexture?: string; // portal_track_mip source key (prefixed, e.g. 'P/mip')
mipTextureSize?: [number, number]; // overlay (mip) texture size [w, h] (px), default 32×32
margin?: number; // overlay wrap margin beyond the tie's outer edge (px, avoids z-fighting), default 0.1
}All inputs needed to generate the track.
export interface TrackConfig {
gaugePx: number; // gauge (px, 1/16 block) = center distance between the left/right rails
heightPx: number; // rail height above the model's bottom face (px, 1/16 block)
wholeModelYOffset?: number; // whole-model (tie + track) Y offset (px), default 0
parts: {
left: PartModel;
right: PartModel;
tie: PartModel;
};
portal?: PortalConfig; // optional portal config; the two textures are independently optional
}The generated result for one track shape. meshes places the parts' mesh geometry like the cubes, so
mesh-only parts also appear in every directional shape.
export interface ShapeSpec {
id: string; // TrackShape id, e.g. 'x_ortho', 'diag', 'ascending_south'
name: string; // display name (Group name)
cubes: CubeSpec[];
meshes?: MeshSpec[]; // mesh geometry contributed by the parts, placed/rotated like the cubes
}