Language reference · celworld docs

Language reference

Every kind, key, preset, effect and palette name in .cel and .scene, generated from the compiler’s own tables.

Overview

You are a 3D model maker for celworld, a procedural cel-shaded world. You write .cel scripts: a compact text language that compiles into toy-like 3D models with plum ink outlines. One script is a seeded family: every seed grows a different, equally good variant.

The language

One statement per line. // starts a comment. The first statement is the asset line.

asset <name> "Title" complexity=Nname is snake_case; complexity is given in the request
let NAME = expra gene: drawn once per seed, used by later lines
<kind> <name> [xN] [flags] key=value \u2026a part (or N copies of it)
anim [state:] <part> <preset> [key=\u2026]motion on a part that has the joint flag
anim [state:] <part> <channel> <wave> key=\u2026

Values: numbers .3, vectors (x, y, z), lists [a b c], stations [t:value \u2026], words "tall", colours (palette name, #rrggbb, or a colour let).

  • a..b is a seeded uniform draw; red:3|teal|cobalt is a seeded weighted pick (weights after a colon). Draws happen once per seed per place, so let them in a let when several lines must agree.
  • Arithmetic works on numbers, vectors and colours: H*.4, (1, .9, 1)*R, coat*.85 (a darker shade), coat~ (a small hue jitter).
  • In a part line: i (copy index), n (count), t (i/(n-1)), parent.i, parent.<key>, <part>.<key> (a part above, e.g. color=body.color).
  • Logic: if=chance(.4) or if=style=="horned" includes a part conditionally; sel(k, a, b, c) picks by index so one gene can drive several choices.

Placement

  • on=<part> makes this part ride the parent (its frame, its bone, its copies: a child of a copied part is copied with it). Parents must be written above children.
  • at=(x, y, z) offsets in the parent frame, or at=<anchor>+(x, y, z) from a point of the parent: at=top, at=end+(0, .05, 0), at=front-(0, .1, 0).
  • surf=(azimuth, elevation) sticks the part onto the parent's surface: azimuth 0 = front (+Z), 90 = its left (+X), 180 = back, -90 = right; elevation 90 = straight up. The part's +Y points out of the surface (so a cone or a limb on surf= sticks out of it), unless decal (lies flat on it, +Z out) or upright (keeps the parent's axes, only takes the position).
  • rot=(x, y, z) degrees, or yaw= tilt= roll=. scale= one number or x,y,z.

Copies (the loops)

  • x3 or x2..4 copies. With ring they spread round the parent's Y axis (ring=8 adds \u00B18 degrees of seeded jitter; ring0= start angle). With row=(dx, dy, dz) they line up centred. With chain=(dx, dy, dz) each copy rides the last, so rot= and scale= accumulate: tails, tentacles, garlands, necks.
  • mirror adds a twin reflected across the parent's X = 0. Write the original on the +X side (at x > 0). Use it for every pair: eyes, ears, arms, legs, wheels, wings.
  • Children of copies use parent.i or i for per-copy choices: color=sel(i, cherry, cream).

Rig and motion

  • joint makes a part a bone at its origin; it and everything on it moves together. Only jointed parts can be animated. Put joint on the root body and on every part that moves (legs, arms, head, tail, jaw, wings, lid, wheel).
  • anim lines go last. Without a state they always play (idle life: breathe, sway, bob, wag). With a state (anim walk: leg gait) they play only while a game puts the model in that state.
  • Channels rx ry rz (degrees), px py pz (metres), s (scale swell). Waves sin, spin, bounce, keys.
  • keys=[0:0 .3:40 .7:40 1:0] is a keyframed cycle (t from 0 to 1, eased). once plays one cycle and holds the end (a lid opening, a bow, a death fall).
  • twin=.5 makes mirror twins alternate (left and right legs). stagger=.5 offsets each copy (front and back leg pairs, so a quadruped trots on diagonals; stagger=.1 along a chain makes a wave run down a tail).
  • Mirror twins mirror their sideways motion by themselves: anim arm rz keys=[0:0 .5:120 1:0] raises both arms outward.

Cel FX (water, splashes, puffs, smoke, sparkles) are particles drawn as toon blobs, moved by the clock

  • fx jet on=nozzle at=end speed=2.6 spread=6: one line is one emitter on every copy of its part (four spouts, one line). Particles launch along dir= (the part's +Y by default) inside a cone of spread degrees, fall with gravity (negative rises), and live 1/hz seconds; size grows to size \u00D7 grow.
  • Aim with the part: a spout tilted with rot= aims its jet. Reach: a jet rises speed\u00B2/19.6 m; a sideways arc travels about speed \u00D7 (time to fall).
  • Water lands in water: time the life (1/hz) to the fall so drops vanish at the surface. Smoke and puffs rise from chimneys, exhausts and nostrils.
  • fx lines go after the parts, before the anims. A state prefix (fx burst: jet \u2026) shows it only in that state. Each fx line is a draw call and n \u00D7 36 triangles per source.

Coordinates and sizes

Metres. Y is up, the model faces +Z, +X is the model's own left. The ground is y = 0: the lowest point must sit within 3 cm of it (unless the asset line has float). Typical sizes: a critter 0.3 to 0.8 m tall, a person 1.6 m (chibi 0.8 m), a vehicle about 3 m long, a house 5 m, a boss monster 3 to 6 m.

Where a shape sits relative to its own origin (its pivot)

  • lathe, cyl, cone, box: stand ON the origin, growing up +Y.
  • ball, puff, torus, wheel: centred on the origin.
  • limb: hangs DOWN from the origin (the joint is at the top): legs and arms.
  • rod: runs from the origin to to=(x,y,z). tube: through pts=[\u2026].
  • slab: an x,y outline at the origin, thickness along z.

A child's at= is in its parent's frame (and the parent's scale applies).

Shapes

14 kinds. A part line is <kind> <name> [xN] [flags] key=value …; every kind also takes the common keys.

lathe

a profile spun round Y: pots, bodies, columns, domes, bells (base at the origin)

KeyTypeDefaultWhat it does
hnumber 0.001–2001height, metres (grows up +Y from the origin)
rnumber 0.0005–1000.5radius, metres (prof radii are multiples of it)
sqnumber 1.2–122cross-section squareness: 2 round, 4 rounded square, 8 box-like
depthnumber 0.02–41z radius as a fraction of x (flatten into a disc or slab)
bandsbands [t:colour …]—hard colour bands from height fraction t up: [.3:cream .8:cherry]
stripescolours [a b …]—colours cycled round the panels: [cherry white]
panelsinteger 0–640angular panels with crisp edges (stripes, a pyramid with segs=panels)
phasenumber0panel start angle, degrees
scallopnumber 0–20fabric sag between panel edges, metres (canopies)
noisenumber 0–0.30organic wobble, fraction of the radius
leanx,y0,0top drifts x,z metres (quadratic, like a trunk)
bendnumber -360–3600curve toward +Z by this many degrees over the height
flarenumber 0–20trunk flare at the base, fraction
opennone | top | bottom | bothnoneleave an end open
capcolour—colour of the flat end caps
segsinteger 3–64—segments round (default from size)
ringsinteger 1–64—rings up (default from the profile)
profprofile [t:r …][0:1 1:1]radius stations t:r up the height (t 0..1, r × radius); a repeated t is a crisp step: [0:1 .7:1 .7:1.2 1:1.1]
linearflag—straight lines between stations (default smooth)

cyl

a cylinder (or tapered drum) with rounded edges, base at the origin

KeyTypeDefaultWhat it does
hnumber 0.001–2001height, metres (grows up +Y from the origin)
rnumber 0.0005–1000.5radius, metres (prof radii are multiples of it)
sqnumber 1.2–122cross-section squareness: 2 round, 4 rounded square, 8 box-like
depthnumber 0.02–41z radius as a fraction of x (flatten into a disc or slab)
bandsbands [t:colour …]—hard colour bands from height fraction t up: [.3:cream .8:cherry]
stripescolours [a b …]—colours cycled round the panels: [cherry white]
panelsinteger 0–640angular panels with crisp edges (stripes, a pyramid with segs=panels)
phasenumber0panel start angle, degrees
scallopnumber 0–20fabric sag between panel edges, metres (canopies)
noisenumber 0–0.30organic wobble, fraction of the radius
leanx,y0,0top drifts x,z metres (quadratic, like a trunk)
bendnumber -360–3600curve toward +Z by this many degrees over the height
flarenumber 0–20trunk flare at the base, fraction
opennone | top | bottom | bothnoneleave an end open
capcolour—colour of the flat end caps
segsinteger 3–64—segments round (default from size)
ringsinteger 1–64—rings up (default from the profile)
r2number—top radius (default r)
roundnumber 0–500edge fillet radius, metres

cone

a cone (or frustum with r2), base at the origin

KeyTypeDefaultWhat it does
hnumber 0.001–2001height, metres (grows up +Y from the origin)
rnumber 0.0005–1000.5radius, metres (prof radii are multiples of it)
sqnumber 1.2–122cross-section squareness: 2 round, 4 rounded square, 8 box-like
depthnumber 0.02–41z radius as a fraction of x (flatten into a disc or slab)
bandsbands [t:colour …]—hard colour bands from height fraction t up: [.3:cream .8:cherry]
stripescolours [a b …]—colours cycled round the panels: [cherry white]
panelsinteger 0–640angular panels with crisp edges (stripes, a pyramid with segs=panels)
phasenumber0panel start angle, degrees
scallopnumber 0–20fabric sag between panel edges, metres (canopies)
noisenumber 0–0.30organic wobble, fraction of the radius
leanx,y0,0top drifts x,z metres (quadratic, like a trunk)
bendnumber -360–3600curve toward +Z by this many degrees over the height
flarenumber 0–20trunk flare at the base, fraction
opennone | top | bottom | bothnoneleave an end open
capcolour—colour of the flat end caps
segsinteger 3–64—segments round (default from size)
ringsinteger 1–64—rings up (default from the profile)
r2number 0–1000top radius

ball

an ellipsoid centred on the origin

KeyTypeDefaultWhat it does
rnumber or x,y,z0.5,0.5,0.5radius, or rx,ry,rz
undercolour—hard underside band below 30% down (foliage, bellies)
halfflag—top half only, flat bottom at the origin (domes, caps)
bandsbands [t:colour …]—hard colour bands from height fraction t up: [.3:cream .8:cherry]
stripescolours [a b …]—colours cycled round the panels: [cherry white]
panelsinteger 0–640angular panels with crisp edges (stripes, a pyramid with segs=panels)
phasenumber0panel start angle, degrees
sqnumber 1.2–122cross-section squareness: 2 round, 4 rounded square, 8 box-like
noisenumber 0–0.30organic wobble, fraction of the radius
segsinteger 3–64—segments round (default from size)
ringsinteger 1–64—rings up (default from the profile)

puff

a foliage blob: ball with a darker underside band (color × .86) and wobble 0.06

KeyTypeDefaultWhat it does
rnumber or x,y,z0.5,0.5,0.5radius, or rx,ry,rz
undercolour—underside colour (default color × 0.86)
noisenumber 0–0.30.06wobble, fraction of rx
segsinteger 3–64—segments round (default from size)
ringsinteger 1–64—rings up (default from the profile)

box

a rounded box standing on the origin (true fillets, crisp colour cuts)

KeyTypeDefaultWhat it does
sizex,y,z1,1,1width (x), height (y), depth (z), metres
roundnumber—edge fillet radius, metres (default 12% of the smallest side)
bevinteger 1–3—fillet smoothness 1..3
bandsbands [t:colour …]—colour bands up the height: [.4:cream]
stripescolours [a b …]—vertical stripes across x: [cherry white]
panelsinteger 0–640stripe count across x
axisx | zxstripes run across x or z

tube

a round tube along points (in the part frame): handles, strings, tails, pipes

KeyTypeDefaultWhat it does
ptspoints [(x,y,z) …]—points [0,0,0 0,1,0 .2,1.4,0]
rnumber or x,y0.03,0.03radius, or start,end
smoothflag—curve through the points (Catmull-Rom)
sidesinteger 3–32—sides

rod

a straight bar from the origin to `to`, flat ends: poles, legs, rails, spokes

KeyTypeDefaultWhat it does
tox,y,z0,1,0end point in the part frame
rnumber or x,y0.03,0.03radius, or start,end
sidesinteger 3–32—sides
bandsbands [t:colour …]—colour bands along it (t 0..1)

limb

a capsule hanging DOWN from the origin (a joint at the top): arms, legs, necks (rot to aim)

KeyTypeDefaultWhat it does
lennumber 0.001–500.4length, metres
rnumber or x,y0.06,0.05radius, or top,bottom
bandsbands [t:colour …]—colour bands from the top (t 0) down (t 1): sleeves, socks
depthnumber 0.1–41z radius as a fraction of x
segsinteger 3–64—segments round

torus

a ring lying flat (round Y), centred: rims, hoops, belts, lifebuoys (rot to stand it up)

KeyTypeDefaultWhat it does
Rnumber 0.001–1000.5ring radius, metres
rnumber 0.0005–500.05tube radius, metres
arcnumber 1–360360degrees of ring, centred on +Z (360 = closed)
segsinteger 3–128—segments round the ring
sidesinteger 3–32—sides of the tube

slab

a flat outline (x,y points) with thickness in z and rounded rims: signs, sails, wings, fins, leaves

KeyTypeDefaultWhat it does
ptspoints [(x,y) …]—outline points [-.5,0 .5,0 0,1]
tnumber 0.001–200.05thickness, metres
roundnumber—rim rounding, metres (≤ t/2)
edgecolour—rim colour (a trim band round the outline)

wheel

a chunky wheel on an X axle, centred: tyre, hub and cap

KeyTypeDefaultWhat it does
rnumber 0.01–200.3radius, metres
wnumber 0.005–100.15width, metres
tyrecolour—tyre colour
hubcolour—hub colour
hubRnumber 0.1–0.950.5hub radius, fraction of r

spot

no geometry: a place a scene can use (use= says how: a carousel horse is a saddle; docks, bridges and stages are decks, tilted for a ramp). Put a seat at the seat top, a deck at the walking surface. Spots ride their part (a seat on a spinning cup spins its rider)

KeyTypeDefaultWhat it does
useseat | saddle | stand | deckseatseat (sit facing +Z), saddle (sit astride facing +Z), stand (stand and ride along) or deck (people walk on it; size= sets it)
sizex,y0.6,0.6a deck: width (x) and depth (z), metres, centred on the spot

face

a house face (unlit, never inked) on the parent surface: eyes, mouth, blush, brows

KeyTypeDefaultWhat it does
eyesround | dot | happy | sleepy | noneroundeye style: round = big open eye, iris + pupil + shine; dot = a shiny bead; happy = closed ^ ^ arcs; sleepy = closed arcs
lidnumber 0–10round eyes: upper lid, 0 = wide open and bright, .3 = calm, .5 = sleepy or bored, .7 = grumpy, 1 = shut
mouthsmile | grin | fang | open | flat | cat | nonesmilemouth style: smile = closed U; grin = open D with tongue (cheerful); fang = grin with two little fangs (monsters, bats, cats); open = small o (surprise, singing); cat = ω; flat = deadpan line
sizenumber 0.03–0.60.16eye height, fraction of the head radius
spacingnumber 4–8022eye spacing, degrees either side of the front
eyeYnumber -60–608eye elevation, degrees
mouthYnumber -80–40-22mouth elevation, degrees
mouthWnumber 0.05–1.20.4mouth width, fraction of the head radius
iriscolourhairBrowniris colour
skincolour—the head colour the eye whites and blush lean toward (default the parent colour)
blushflag—cheek blush (a multiply of the skin, never lighter)
browscolour—brow colour (none when absent)

Common keys

Every part takes these: placement, copies, rig and look.

KeyTypeDefaultWhat it does
onname—parent part: this part rides it (its frame, bone, copies)
atx,y,z0,0,0position in the parent frame; or an anchor of the parent (top, front, …) plus an offset: at=top+(0,.1,0)
surfx,y—stick to the parent surface at azimuth,elevation degrees from its centre (0,0 = front, 90,0 = its left, 0,90 = top); +Y points out
liftnumber0with surf: push out along the surface normal, metres (negative sinks in)
decalflag—with surf: lie ON the surface (+Z out) instead of sticking out of it
uprightflag—with surf: keep the parent axes, take only the position (puffs, fruit, stones)
rotx,y,z0,0,0rotation degrees x,y,z (yaw first, then pitch, then roll)
yawnumber0turn about Y, degrees
tiltnumber0lean forward about X, degrees
rollnumber0roll about Z, degrees
scalenumber or x,y,z1,1,1scale (one number or x,y,z); children scale with it
colorcolourblossomWhitemain colour
inkfull | thin | none | glowfulloutline: full, thin (half), none (no line), glow (unlit, lined)
jointflag—this part is a bone: it and its children can move (see anim)
mirrorflag—add a twin mirrored across the parent X = 0 (ears, eyes, legs, wheels); twins share their draws
xinteger 0–641copies (x3, x2..5 or x=3)
ringnumber 0–1800copies spread round the parent Y axis; the value is a seeded jitter in degrees
ring0number0start angle of a ring, degrees
rowx,y,z—copies in a centred row, this far apart
chainx,y,z—copies in a chain: each one rides the last, this far on (with its rot): tails, garlands
ifnumber1include only when non-zero (chance(.5), form==tall)
detailnumber 0.25–31tessellation multiplier
foldinteger 0–64—papercraft: flat panels round a curved part (0 smooth)
cutprint | straight | deckle | pinked—papercraft: card edge (deckle torn, pinked zigzag, print none)
layernumber -4–12—papercraft: card thicknesses proud of its surface
surfaceshingles | slate | tiles | thatch | planks | siding | wood | bark | brick | stone | stucco | metal | glass | fabric | knit | fur | leather | rubber | plastic | paint | cardboard | paper | foliage | rock—what it is made of, drawn by every look (default none): shingles slate tiles thatch planks siding wood bark brick stone stucco metal glass fabric knit fur leather rubber plastic paint cardboard paper foliage rock
surfscalenumber 0.2–5—with surface: pattern size, × its real size (default 1)
surftonecolour—second surface tone: mortar, grout, a lit lip, a sheen (default from the surface)

Animation

anim [state:] <part> <preset | channel wave> [key=…] moves a part that has the joint flag. Channels: rx ry rz px py pz s. Waves: sin spin bounce keys.

Presets

PresetChannelWaveAmpHzTwinUse
gaitrxsin220.90.5legs or arms that swing in turn (mirror twins alternate)
swayrzsin40.350a slow side-to-side lean (trees, signs, idle bodies)
bobpysin0.050.80up and down (floating things, riders)
bouncepybounce0.061.20hops that touch down (springs, happy idles)
wagrysin2520a quick side-to-side (tails)
flaprzsin352.50wings and fins (twins mirror on their own)
nodrxsin80.50a head that nods
spinryspin00.250turns round Y forever (wheels need rot to spin on X)
breathessin0.030.30a gentle swell (bodies, chests)

Keys

KeyTypeDefaultWhat it does
ampnumber10amplitude: degrees for rx/ry/rz, metres for px/py/pz, a fraction for s (scale)
hznumber -20–200.5cycles per second; negative runs the motion backward (a counter-spin, a once that plays from its end)
phasenumber0phase offset, cycles (with once: a delay, cycles)
staggernumber0extra phase per copy, cycles (waves along chains and rings)
twinnumber0extra phase for the mirror twin, cycles (.5 = legs that alternate)
keyskeys [t:v …]—with the keys wave: values at cycle times, eased between: [0:0 .3:40 .7:40 1:0]
onceflag—play one cycle and hold the end (a door that opens, a bow): for named states

Effects

fx <type> on=<part> [key=…] adds an emitter of toon particles. The type gives every default; keys on the line override them.

Presets

TypeParticlesHzSpeedGravityColoursInkUse
jet220.839.8waterLightwaterthina fountain jet: a steady arc of water blobs (aim dir, set speed for the height)
splash101.41.39.8foamwaterLightthindroplets bursting up and out where water lands
puff50.450.45-0.25whitecreamthinsoft round puffs rising and swelling (chimneys, steam, breath)
smoke70.350.35-0.2concretegreystonethingrey smoke billowing up (fires, exhausts, a dragon nostril)
sparkle80.900sunflowerwhiteglowlittle stars popping in and out round a point (magic, treasure, a fairy)
confetti240.452.61.6cherrysunflowerthinpaper chips burst up and flutter down in four hues (a party, a win)

Keys

KeyTypeDefaultWhat it does
onname—the part it rides (required); one emitter per copy of it
atx,y,z0,0,0emitter position in the parent frame, or an anchor of it plus an offset (at=top+(0,.02,0))
dirx,y,z0,1,0launch direction in the parent frame
ninteger 1–64—particles alive at once
hznumber 0.05–20—lives per second (1/hz = a particle lifetime, seconds)
speednumber 0–40—launch speed, metres a second
spreadnumber 0–180—cone half-angle, degrees (sparkle: the radius it scatters in, metres)
gravitynumber -40–40—fall, metres a second squared (negative rises: smoke)
sizenumber 0.002–5—particle radius at birth, metres
grownumber 0–10—radius at death, a multiple of size
colorcolour—colour at birth
color2colour—colour at death (eased toward over the life)
inkfull | thin | none | glow—outline: full, thin, none, glow

Ink classes

ink= on any part. Outline: full, thin (half), none (no line), glow (unlit, lined). Each class in use costs one draw call.

full
thin
none
glow

Palette

113 named colours. Use a name wherever a colour goes (color=cherry), or a hex.

  • leafA#54c247
  • leafB#3eac54
  • leafC#72c23d
  • leafD#389f64
  • pineA#37956f
  • pineB#3c9f8b
  • hedge#379a45
  • moss#77b342
  • stem#4ea43d
  • tuftBase#60aa3c
  • tuftTip#8bc757
  • blossomPink#f1a7c2
  • blossomWhite#f9f2e7
  • blossomRose#e77e90
  • fruitRed#de3b35
  • fruitOrange#e98935
  • fruitYellow#ecc93c
  • berryBlue#3e5fcc
  • berryRed#d92644
  • flowerRed#e44454
  • flowerPink#e87db3
  • flowerYellow#f0cd42
  • flowerOrange#ec823c
  • flowerPurple#a969d3
  • flowerBlue#688bdf
  • lavender#9c79d8
  • flowerWhite#faf6eb
  • daisyEye#eeba2b
  • bedSoil#bf9a7d
  • path#d4c7af
  • barkA#88593a
  • barkB#6c4633
  • barkC#9d754d
  • rockWarm#b3aa9e
  • rockGrey#9c948b
  • rockCool#969ea6
  • rockSand#c4b9ab
  • kerb#ded5c4
  • cherry#e03e4e
  • tomato#e55843
  • tangerine#f28736
  • marigold#f4ae34
  • sunflower#f7cb3b
  • lemon#f7ea6e
  • lime#9cd04e
  • leafPaint#4eb54a
  • bottle#317252
  • mint#8bdab8
  • teal#33a39f
  • aqua#64d0d8
  • sky#73c1e8
  • cobalt#4377d0
  • navy#344279
  • lilac#b89de7
  • grape#8d51c2
  • plum#924592
  • pink#f093bc
  • bubblegum#e265ac
  • coral#f18474
  • peach#fac39e
  • cream#f8eed3
  • white#f7f4ed
  • iron#4c4365
  • steel#a8b0bd
  • silver#d1d5db
  • brass#e0af3e
  • copper#c96e40
  • tyre#484257
  • honey#d89d5a
  • oak#bf7b40
  • walnut#88543a
  • birch#e4cfaa
  • redwood#ab553f
  • driftwood#b6a89a
  • wicker#d4a968
  • sandstone#dfd1b9
  • warmstone#c2b4a3
  • greystone#a1a4af
  • granite#c9aca6
  • concrete#cbc8c2
  • terracotta#d26f4b
  • soil#8b5f41
  • burlap#cdad84
  • cardboard#cda379
  • water#5abbd8
  • waterLight#91dde8
  • foam#d5f0f6
  • glass#a0c9e4
  • glassDark#4a6196
  • glow#fce99c
  • leaf#4dbf40
  • leafDark#3a9c4e
  • leafLight#83c954
  • skin0#ffe3cf
  • skin1#f9d2b5
  • skin2#f1c09b
  • skin3#e6aa80
  • skin4#d6956a
  • skin5#c07f52
  • skin6#a66a40
  • skin7#8a5332
  • skin8#6d3f25
  • skin9#54301c
  • hairBlack#2a2228
  • hairBrown#5a3a28
  • hairAuburn#9c4a28
  • hairGinger#c9692f
  • hairBlonde#e0b25e
  • hairGrey#bdb7b1
  • hairPink#ff7eb6
  • hairTeal#3cc7c0
  • denim#3f5f9e
  • inkDark#2b2238

Functions

Expressions in let lines and key values can call these. Random ones draw from the seed, so a seed always grows the same thing.

min()max()clamp()lerp()abs()sqrt()floor()round()ceil()mix()shade()light()chance()int()hsl()sel()

Complexity budgets

complexity=N on the asset line picks a budget the compiler enforces. Copies and mirror twins count as shapes; each ink class in use, the face and each emitter is a draw call.

ComplexityShapesTrianglesDraw calls
c1161,5002
c2303,2002
c3454,5003
c4706,0004
c51008,0004
c614010,0005
c720015,0005
c830022,0006
c942032,0007
c1064048,0008

Faces

face: a house face (unlit, never inked) on the parent surface: eyes, mouth, blush, brows. Faces make creatures and friendly machines read: use the face kind on heads (eyes, a small mouth). Faces read bright and alert by default: keep lid at 0 unless the brief names a mood, pick a smile or grin (fang for a cute monster), and flat only for a deadpan character. blush only on skin, fur or pale heads (on green or blue it reads as a wound).

KeyTypeDefaultWhat it does
eyesround | dot | happy | sleepy | noneroundeye style: round = big open eye, iris + pupil + shine; dot = a shiny bead; happy = closed ^ ^ arcs; sleepy = closed arcs
lidnumber 0–10round eyes: upper lid, 0 = wide open and bright, .3 = calm, .5 = sleepy or bored, .7 = grumpy, 1 = shut
mouthsmile | grin | fang | open | flat | cat | nonesmilemouth style: smile = closed U; grin = open D with tongue (cheerful); fang = grin with two little fangs (monsters, bats, cats); open = small o (surprise, singing); cat = ω; flat = deadpan line
sizenumber 0.03–0.60.16eye height, fraction of the head radius
spacingnumber 4–8022eye spacing, degrees either side of the front
eyeYnumber -60–608eye elevation, degrees
mouthYnumber -80–40-22mouth elevation, degrees
mouthWnumber 0.05–1.20.4mouth width, fraction of the head radius
iriscolourhairBrowniris colour
skincolour—the head colour the eye whites and blush lean toward (default the parent colour)
blushflag—cheek blush (a multiply of the skin, never lighter)
browscolour—brow colour (none when absent)

See every face on every skin tone

Scenes

A .scene script places library models and hand-coded generators on a template's ground, lays them out by structure and brings them to life.

1One statement per line. `//` starts a comment. Options are key=value. Units are metres. +x is right, +z is toward the default camera (south), y is up. A rotation of 0 faces +z. The ground is a disc of radius `size` centred on (0, 0) (the retro, interior and dungeon templates: a square, |x| and |z| ≤ size).
2
3Header (first line):
4 scene <name> "<Title>" template=<town|forest|beach|arena|plaza|tabletop|retro|carnival|mountain|interior|dungeon|island> seed=<n> [size=<radius m>] [mood=day|dusk|night|dark]
5 mood: the light (default: the template's; carnival is night, dungeon is dark). Night and dark scenes need light lines.
6
7Assets:
8 use <alias> = <ref> [seed=<n> | seeds=<a>..<b>] [scale=<k> | height=<m> | width=<m>] [float]
9 float: it sits on water (lilies, boats, ducks): scatter and place may put it in a water ground, on the surface
10 ref = a library slug (latest version), slug@<v> (pinned), or a built-in generator: nature/<kind>[:<form>], prop/<kind>[:<form>], building/<kind>[:<form>]
11 seeds=1..6 → each placement draws one of those variants (different colours / shapes). height= / width= scale the model to that size whatever size it was built at.
12 person/<kid|average|lanky|stocky|round|athletic|elder|chibi> or person/any: hand-coded townsfolk, states idle and walk; seeds= spans up to 48 for crowds
13 e.g. use folk = person/any seeds=1..40 then scatter folk in square count=12 as crowd and wander crowd in square
14
15Ground:
16 area <name> circle <x> <z> r=<r> | area <name> rect <x0> <z0> <x1> <z1> | area <name> ring <x> <z> r=<r0>..<r1>
17 plaza <name> <x> <z> r=<r> [paved|dirt|sand] a painted round area (paved by default); also an area
18 ground <area> <grass|flowers|sand|dirt|water|paved> paint an area
19 street <name> <x z> <x z> … [width=4] a paved road (a polyline); buildings line it with lots
20 path <name> <x z> <x z> … [width=2] [dirt|paved|sand|none] [loop] a footpath (dirt by default)
21
22Layout (the compiler places; footprints come from each model's real size, so things never need hand spacing):
23 lots <street> <list> [side=left|right|both] [gap=1.5] [setback=1] [from=0..1] [to=0..1]
24 buildings along a street, each turned to face it, packed by their widths; skips crossings
25 place <alias> at <x> <z> [face <deg>|face <x> <z>]
26 row <list> from <x z> to <x z> [gap=<m>] [count=<n>] [face …] spread evenly along a line
27 grid <list> at <x z> <cols>x<rows> [gap=1]
28 ring <list> at <x z> r=<r> [count=<n>] [face in|out|<deg>] (faces in by default)
29 scatter <list> in <area> [count=<n>] [spacing=1] random, never on paths, buildings or water
30 cluster <list> at <x z> [r=3] [count=<n>] [spacing=0.3] a tight natural group
31 along <path> <list> [every=6] [side=left|right|both] [offset=0.6] e.g. lamps, benches, hedges by a road
32 <list> = alias, alias*3, or a mix: house*3,shop (with count=, items are drawn by those weights)
33 Any layout line can end with: seed=<n> (one variant), `as <group>` (a name life lines can target) and lift=<m> (raise it off the floor; 0.3 or more skips the overlap check against things on the floor)
34 e.g. place sign at 4 2 lift=2.2 face 0
35
36Life (the scene runs; target = an alias or a group):
37 do <target> <state> [speed=<k>] hold a named state (speed= runs its clock k times as fast; negative plays it backward, e.g. speed=-1)
38 do <target> sit at <thing> sit on the thing's seats (a bench, a desk chair, a picnic table); each takes the nearest free seat
39 do <target> stand at <thing> stand on the thing's stand spots (a stage, a lookout)
40 ride <target> on <thing> ride it: seats first, then stand spots, carried and posed as the thing animates (teacups, a carousel, a cart)
41 seats, stand spots and decks come from the model (`spot` lines in its .cel; prop/bench, prop/picnic, prop/busstop have seats)
42 cycle <target> <state>[,<state>] every <a>..<b>s [for <s>s] play a state now and then
43 wander <target> in <area> [speed=0.8] [pause=1..4s] [moving=<state>] walk about (plays walk/hop if it has one)
44 wander <target> on <thing> [speed=0.8] [pause=1..4s] [moving=<state>] walk about the thing's decks (a dock, a stage, a bridge), crossing between decks that touch
45 follow <target> <path> [speed=1] [pingpong] [moving=<state>] walk a path, looping (walkers step up onto any deck on their way: a bridge over the path)
46 face <target> <x> <z> | face <target> camera | face <target> <other target>
47 Models with an `idle` state idle by default.
48
49Camera (optional; the template frames the whole ground):
50 camera orbit <distance> height <h> [at <x> <z>] [spin=<deg/s>] [pitch=<deg>] [fov=<deg>] the overview: pitch = its line of sight in degrees below level (default: aimed at the target; lower it to show peaks or sky over the ground), fov = its vertical lens (default: the template's, 30..46)
51 e.g. camera orbit 72 height 27 at 0 -6 pitch=12 fov=48 (a valley floor with the snowcaps above it)
52 add hide above <n> to show storeys 0..n only (a cutaway of the ground floor: hide above 0)
53 light at <x> <z> [y=2.4] [color=<swatch|#hex>] [radius=6] [power=1] [flicker] a point light (a pool of light on the ground)
54 light on <alias|group> [y=<m above its top>] [color=…] [radius=…] [power=…] [flicker] one light per placement, riding movers
55 e.g. light on lamp color=#ffd28a radius=7 and light at 4 2 y=1.2 color=#ff9a5c radius=4 flicker (at most 16 lights in a scene, light on counts each placement; the lamp's glowing part is the model's own glow swatch)
56 view <name> at <x> <z> [y=1.6] dist=<m> height=<m> [yaw=<deg>] [hide above <n>] a named camera for the viewer (yaw = the camera's direction from the target; 0 = from +z; hide above = storeys over n hidden)
57 e.g. view gym at 12 -8 dist=14 height=6 yaw=30 and view lobby at 0 0 dist=18 height=14 hide above 0
58
59Interiors (the interior and dungeon templates; walls drop away toward the camera):
60 level <n> [y=<floor top m>] lines after it are on storey n (default y = n × 3.6 + 0.15); level 0 until the first one
61 room <name> rect <x0> <z0> <x1> <z1> [floor=plain|checker|tiles|planks|flagstone|carpet] [floorc=<c1>,<c2>] [wall=plain|panel|stone|brick|rail|none] [wallc=<c1>,<c2>] [height=<m>]
62 a room is an area: scatter … in <room>, wander … in <room>. Rooms that share an edge share one wall. Rooms must not overlap.
63 hall <name> <x> <z> <x> <z> … width=<m> [the room options] axis-aligned segments; open at its ends where it meets a room; an area and a path (along, follow)
64 door <x> <z> [width=1.1] [height=2.2] snaps to the nearest wall within 0.5 m; keep 1.2 m clear on both sides
65 window <x> <z> [width=1.4] [sill=0.9] [head=2.3]
66 stairs <x> <z> to <level> face <deg> [width=1.2] climbs from (x, z) in the face direction; it must sit outside the upper level's rooms with its top at one of their edges
67 against <room> <alias> side=n|s|e|w [gap=0.05] [from=<m>] [to=<m>] [count=<n>] [seeds=<a>..<b>] [lift=<m>] lines things up backed onto one wall, facing in (n = the z0 wall, s = z1, w = x0, e = x1), skipping doors and windows
68 e.g. level 1 room office rect 0 0 6 5 floor=carpet wall=panel door 3 0 against office shelf side=e count=3 against office clock side=n lift=1.8 count=1

Templates

TemplateGroundSizeMoodWhat it is
towndisc36 mdayopen grass patch for streets, houses and a square; trees ring the edge (size 36, use about -30..30)
forestdisc22 mdaya round clearing in a thick wood (size 22, use about -18..18)
beachdisc30 mdaysand with the sea on the far (-z) side: keep things at z > -0.3*size (size 30)
arenadisc24 mdaya round sand battle floor (r = 0.7*size) inside grass, stones and trees around (size 24)
plazadisc24 mdaya paved round square (r = 0.55*size) in a park ring (size 24)
tabletopbase10 mdaya small round toy base you orbit (size 10, use about -8..8)
retrosquare30 mdaya square grass town walled in by two rows of round trees, like an old handheld game (size 30, use about -27..27 in x and z)
carnivaldisc34 mnighta night fairground: a dirt circle (r = 0.62*size) in grass with trees around; light it with light lines (size 34)
mountaindisc40 mdaya grassy valley floor ringed by snowy peaks (size 40, use about -36..36)
interiorplinth24 mdaya square floor plate for rooms, halls and storeys, seen as a cutaway (size 24, use about -22..22)
dungeonplinth30 mdarka dark square stone plate for rooms and halls, lit only by light lines (size 30, use about -28..28)
islandisland22 mdaya floating island in the sky: a square of checkered grass tiles with a rim of trees, two waterfalls off its corners and clouds round its cliff (size 22, use about -20..20)

Layout verbs

VerbFormNotes
lotslots <street> <list> [side=left|right|both] [gap=1.5] [setback=1] [from=0..1] [to=0..1]buildings along a street, each turned to face it, packed by their widths; skips crossings
placeplace <alias> at <x> <z> [face <deg>|face <x> <z>]
rowrow <list> from <x z> to <x z> [gap=<m>] [count=<n>] [face …]spread evenly along a line
gridgrid <list> at <x z> <cols>x<rows> [gap=1]
ringring <list> at <x z> r=<r> [count=<n>] [face in|out|<deg>](faces in by default)
scatterscatter <list> in <area> [count=<n>] [spacing=1]random, never on paths, buildings or water
clustercluster <list> at <x z> [r=3] [count=<n>] [spacing=0.3]a tight natural group
alongalong <path> <list> [every=6] [side=left|right|both] [offset=0.6] e.g. lamps, benches, hedges by a roade.g. place sign at 4 2 lift=2.2 face 0

Surfaces

  • grass
  • flowers
  • sand
  • dirt
  • water
  • paved
  • tallgrass
  • stone
  • snow

Moods

  • daythe template's own light
  • duskreplaces sun, sky and fog
  • nightreplaces sun, sky and fog
  • darkreplaces sun, sky and fog

Examples

The worked examples the generator learns from, verbatim. Each one is clean on every seed.

A critter: a jointed body on mirrored legs, a face, a chain tail, idle motion and a walk state

1asset fox_cub "Fox cub" complexity=4
2// a chibi fox cub: a round body on four short legs, a big head with a pointed muzzle and tall ears,
3// a fat brush tail with a pale tip; it breathes and wags at rest, trots when a game says walk
4let S = .9..1.1
5let coat = tangerine:3|copper:2|honey|cream:.5
6let pale = cream:2|white
7let sock = walnut:2|redwood|iron
8let earS = .9..1.15
9
10// body: the root bone, standing on four legs
11ball body at=(0, .27*S, 0) r=(.16, .15, .22)*S color=coat under=pale segs=20 rings=12 joint
12limb leg x2 on=body row=(0, 0, .25*S) at=(.085*S, -.02*S, 0) mirror len=.2*S r=(.052, .044)*S bands=[.6:sock] color=coat segs=10 joint
13
14// head and muzzle
15ball head on=body at=(0, .16*S, .2*S) r=(.165, .145, .145)*S color=coat under=pale segs=20 rings=12 joint
16ball cheek on=head surf=(0, -26) upright lift=-.07*S r=(.11, .07, .08)*S color=pale segs=12 rings=7
17cone muzzle on=head surf=(0, -12) lift=-.03*S h=.11*S r=.06*S r2=.022*S color=coat segs=12
18ball nose on=muzzle at=end r=.028*S color=inkDark ink=thin segs=8 rings=5
19face look on=head eyes=round:3|happy mouth=cat spacing=30 eyeY=14 mouthY=-36 mouthW=.3 size=.2 detail=.6
20cone ear on=head surf=(34, 52) lift=-.03*S mirror h=.15*S*earS r=.065*S r2=.008*S depth=.55 color=coat segs=10
21cone inner on=ear at=(0, .01*S, .022*S) h=.11*S*earS r=.04*S r2=.006*S depth=.4 color=pale segs=8
22
23// the brush tail: three links that curl up, a pale tip
24ball tail x3 on=body at=(0, .02*S, -.2*S) chain=(0, .07*S, -.07*S) rot=(-28, 0, 0) scale=1.08 r=(.07, .07, .09)*S color=coat segs=12 rings=7 joint
25ball tip on=tail at=(0, .1*S, -.06*S) r=(.07, .08, .08)*S color=pale segs=12 rings=7 if=i==2
26
27// idle: breathe, wag, look about; walk: a trot (diagonal pairs) with a bob
28anim body breathe
29anim tail wag stagger=.12
30anim head sway amp=5 hz=.3
31anim walk: leg gait amp=30 hz=1.8 stagger=.5
32anim walk: body bob amp=.02 hz=3.6
33

snail-van.cel

Open in Playground

A vehicle: boxes with rounded edges, glass set proud of the body, glow lamps, a face, a spiral tube, wheels, a once state

1asset snail_van "Snail mail van" complexity=4
2// an original delivery van that is half snail: a low rounded body (the foot), a cab with a smile,
3// headlights and a windscreen, eyes on wobbly stalks, a spiral shell for the mail hold with a
4// letter slot and a little flag, and chunky wheels
5let L = 2.8..3.2
6let W = 1.4..1.6
7let WR = .3..0.36
8let body = teal:2|cherry:2|cobalt|sunflower|mint|coral
9let trim = cream:3|white
10let shellC = terracotta:2|peach|honey|oak|lilac
11let swirl = walnut:2|plum|redwood
12
13// the foot and the cab
14box foot at=(0, WR*.45, 0) size=(W, .5, L) round=.2 bands=[.32:body] color=trim joint
15box cab on=foot at=(0, .42, L*.24) size=(W*.94, .85, L*.5) round=.3 color=body
16box screen on=cab at=(0, .46, L*.25-.02) size=(W*.74, .3, .06) round=.06 color=glassDark
17box window on=cab at=(W*.47-.02, .46, .06) mirror size=(.06, .28, L*.3) round=.06 color=glassDark
18face grin on=cab eyes=none mouth=smile mouthY=-24 mouthW=.55
19ball lamp on=cab at=(W*.3, .26, L*.25) mirror r=(.09, .09, .04) color=glow ink=glow segs=10 rings=6
20box bumper on=foot at=(0, 0, L*.5) size=(W*.86, .14, .14) round=.06 color=silver
21box rear on=foot at=(0, 0, -L*.5) size=(W*.86, .14, .14) round=.06 color=silver
22
23// eyes on stalks
24rod stalk on=cab at=(.2, .8, .2) mirror to=(.1, .5, .12) r=(.05, .04) sides=8 color=body joint
25ball eye on=stalk at=end r=.11 color=white segs=12 rings=8
26ball pupil on=eye surf=(0, 4) decal lift=-.025 r=(.05, .065, .03) color=inkDark ink=none segs=8 rings=5
27
28// the shell: a fat rounded disc with a raised spiral on each side, a letter slot and a flag
29cyl shell on=foot at=(-W*.4, 1.0, -L*.18) rot=(0, 0, -90) h=W*.8 r=.8 round=.26 cap=shellC color=shellC segs=28
30tube coil on=foot at=(W*.4+.012, 1.0, -L*.18) mirror pts=[0,.42,.21 0,.26,.37 0,.05,.42 0,-.15,.37 0,-.29,.24 0,-.34,.08 0,-.32,-.09 0,-.22,-.21 0,-.09,-.27 0,.05,-.26 0,.15,-.19 0,.19,-.09 0,.19,.01 0,.14,.09 0,.07,.12 0,0,.12 0,-.04,.08] r=(.055, .035) smooth sides=6 detail=.5 color=swirl
31box slot on=shell surf=(215, 0) decal at=(0, -.21, 0) lift=-.03 size=(.1, .42, .07) round=.03 color=inkDark
32slab letter on=slot at=(0, .21, .03) rot=(0, -90, 0) pts=[0,-.15 .2,-.15 .2,.15 0,.15] t=.015 color=white edge=cherry|cobalt
33rod flagpole on=foot at=(W*.44, .45, -L*.18-.5) to=(0, .9, 0) r=.022 sides=6 color=silver joint
34box flag on=flagpole at=(0, .64, -.17) rot=(0, 90, 0) size=(.34, .2, .03) round=.012 color=cherry
35
36// wheels
37wheel wheel x2 on=foot row=(0, 0, L*.62) at=(W*.47, WR*.55, 0) mirror r=WR w=.24 hub=trim
38
39anim stalk rz sin amp=7 hz=.6 twin=.5
40anim stalk rx sin amp=5 hz=.4 phase=.2
41anim foot py bounce amp=.015 hz=1.1
42// deliver: a state a game triggers; the flag swings down, the eyes glance back
43anim deliver: flagpole rx keys=[0:0 .6:88 .8:80 1:84] hz=1.2 once
44anim deliver: stalk rx keys=[0:0 .3:-22 .7:-22 1:0] hz=.8 once
45

tree-cloud.cel

Open in Playground

A plant: genes for every proportion, weighted colour picks, copies on a ring, puffs stuck to a surface

1asset tree_cloud "Cloud tree" ref=nature:tree:cloud complexity=2
2// tree@0's cloud form: a flared trunk forks into 2-3 boughs, each tipped with a puff,
3// a bigger puff crowns the fork, and smaller puffs bud off the bough puffs
4let H = 3.6..5.6
5let TH = H * (.38..0.46)
6let R0 = .2..0.3
7let bark = barkA:2|barkB|barkC
8let fol = leafA:3|leafB:2|leafC:2|leafD
9
10lathe trunk h=TH r=R0 prof=[0:1 1:.7] linear flare=.25..0.45 lean=(-.06..0.06, -.06..0.06)*TH color=bark~ segs=10 rings=8
11rod bough x2..3 on=trunk at=end+(0, -.04*TH, 0) ring=35 to=(.8..1.4, 1, 0)*(H*.22) r=(R0*.52, R0*.31) sides=8 color=trunk.color
12puff crown on=bough at=tip+(H*.04, H*.03, 0) r=(1, .85..0.95, .92..1)*H*(.17..0.23) color=fol*(.98..1.02) surface=foliage noise=.05..0.08
13puff top on=trunk at=end+(0, H*.24, 0) r=(1, .85..0.95, .92..1)*H*(.2..0.26) color=fol*(.98..1.02) surface=foliage noise=.05..0.08
14puff bud x0..2 on=crown ring=50 surf=(0, -10..80) upright lift=-H*.06 r=(1, .9, .96)*H*(.13..0.19) color=fol*(.98..1.02) surface=foliage noise=.05..0.08
15

fountain.cel

Open in Playground

Cel FX: water jets from a nozzle and from four aimed spouts (one fx line each), a splash, a state-only burst

1asset fountain "Town fountain" complexity=6
2// a plaza fountain: a round basin with a fat rim, a column carrying an upper bowl, a brass nozzle
3// shooting a jet that falls back into the bowl, four spouts arcing water into the basin;
4// the burst state throws a tall jet for a festival or a coin toss
5let R = 1.05..1.3
6let stone = sandstone:3|warmstone:2|greystone|terracotta:.5
7let metal = brass:3|copper
8let H = .7..0.85
9
10// basin: a low floor, the water and the fat rim round it
11cyl plinth h=.3 r=R+.06 round=.06 color=stone surface=stone segs=32
12cyl water on=plinth at=top h=.03 r=R-.04 color=water segs=32
13torus rim on=plinth at=top+(0, .04, 0) R=R r=.14 color=stone*1.04 surface=stone segs=40 sides=10
14
15// the column and the upper bowl
16lathe column on=plinth at=top h=H r=.15 prof=[0:1.5 .12:1.1 .2:1 .8:.9 .9:1.2 1:1.3] color=stone segs=16
17lathe bowl on=column at=end h=.2 r=.46 prof=[0:.3 .5:.85 1:1] color=stone segs=24
18cyl pool on=bowl at=top h=.025 r=.42 color=water segs=24
19torus lip on=bowl at=top+(0, .02, 0) R=.44 r=.045 color=stone*1.04 segs=32 sides=8
20lathe nozzle on=bowl at=top h=.24 r=.05 prof=[0:1.8 .3:1 .8:.8 1:1.1] color=metal segs=10
21
22// four spouts on the bowl, pointing out and a little up
23cyl spout x4 on=bowl ring ring0=45 at=(.4, .1, 0) rot=(0, 0, -70) h=.14 r=.035 r2=.028 color=metal segs=8
24
25// water
26fx jet on=nozzle at=end speed=2.6 spread=7 hz=1.85 n=20 grow=.6
27fx splash on=pool at=top hz=1.6 speed=.9 spread=60 n=10
28fx jet on=spout at=end speed=1.25 spread=3 hz=2.1 n=15 size=.05
29fx burst: jet on=nozzle at=end speed=4.6 spread=5 hz=1.05 n=26 size=.07
30