PartScript is a small language for building PSX-style 3D models: props, rooms, ruins, whole buildings
and the hills they stand on. A few words a line, a few dozen lines a scene, compiled to .glb
by one small Rust program. No Blender needed.
Name a shape and put things on it. Rows pack books of drawn sizes tight; stacks pile papers up; nothing is added up by hand. Every copy draws its own size and colour, and the same file always builds the same model.
prop writers_desk "Writer's Desk" layout hero=1 # The desk: a top on four legs, and a bank of two drawers under its right-hand end. top = bevel_box size=1.4,.7,.04 bevel=.01 at=0,0,on(.72) mat=oak legs4 w=1.3 d=.6 h=.72 m=dark_oak drawers = box size=.44,.62,.3 at=top.right-.27,0,on(.42) mat=dark_oak stack on=drawers.front pack=centre gap=.02 { box size=.4,.012,.12 mat=pale_oak repeat 2 } # On it: books along the back, a lamp, a pile of papers with a pen, a cup. books = row x on=top at=-.42,.22 align=back { book repeat 10 } bookend on=top at=books.right+.03,.24 anglepoise on=top at=.5,.18 papers = stack on=top at=-.1,-.12 { paper repeat 7 } pen on=papers at=.06,0 cup on=top at=.22,-.18
Everything here is one of the project's example files, built by PartScript and nothing else.
Ground from noise (terrain), walls knocked apart (break=), things that fall onto what is under them (drop=), moss and ivy over named shapes.
A kit of walls, floors and stairs, laid out room by room on a grid, each room furnished by a part that knows its size and doors.
rand(), pick() and when= make every copy different: no two headstones, books or bones alike. odds() deals each one a fate, as often as you say.
Parts with parameters, imported from other files and called like shapes: furniture.table at=....
Pieces that chain end to end, copies along a line of points, loose ends that join themselves up.
Few triangles, small dithered textures with hard pixels, shading baked into the corners of faces.
From the command line, from Rust, or embedded in a game with your own materials and textures. The output is plain glTF: Godot, Unity, Blender, three.js.
C:\> cargo install --locked --git https://github.com/meowers-dev/partscript partscript-cli partscript check props/ # instant: mistakes and triangle counts partscript build props/ -o out/ # every prop as out/<id>.glb partscript fmt props/a.parts -w # tidy a file partscript ref # the whole language, one page
use partscript::{Host, Project}; let mut p = Project::from_paths( &["props/"], Host::default())?; println!("{:?}", p.check().errors); let lamp = p.build("street_lamp", &Default::default())?; std::fs::write("lamp.glb", lamp.glb)?;