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.
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) orif=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, orat=<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 onsurf=sticks out of it), unless decal (lies flat on it, +Z out) or upright (keeps the parent's axes, only takes the position).lift=moves it out along the normal (negative sinks it in).rot=(x, y, z) degrees, oryaw=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=8adds \u00B18 degrees of seeded jitter;ring0=start angle). Withrow=(dx, dy, dz) they line up centred. Withchain=(dx, dy, dz) each copy rides the last, sorot=andscale=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, blink of motion). 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=.5makes mirror twins alternate (left and right legs).stagger=.5offsets each copy (front and back leg pairs, so a quadruped trots on diagonals;stagger=.1along 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=nozzleat=endspeed=2.6spread=6:one line is one emitter on every copy of its part (four spouts, one line). Particles launch alongdir=(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. sparkle scatters glow stars round a point.
- 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: throughpts=[\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).
Header
The first statement: asset <name> "Title" complexity=N. It takes these keys.
| Key | Type | Default | What it does |
|---|---|---|---|
| title | name | — | display name |
| complexity | integer 1–10 | — | budget tier 1..10: caps shapes, triangles and draw calls (an error past them) |
| tris | integer 100–200000 | 6000 | triangle budget without a complexity (a warning past it) |
| ref | name | — | hand-coded counterpart for the playground compare view, e.g. tree:cloud |
| float | flag | — | the model is meant to hover (no ground-contact warning) |
| scale | number | — | lab hint: how big one grid cell should be, metres |
Shapes
13 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)
| Key | Type | Default | What it does |
|---|---|---|---|
| h | number 0.001–200 | 1 | height, metres (grows up +Y from the origin) |
| r | number 0.0005–100 | 0.5 | radius, metres (prof radii are multiples of it) |
| sq | number 1.2–12 | 2 | cross-section squareness: 2 round, 4 rounded square, 8 box-like |
| depth | number 0.02–4 | 1 | z radius as a fraction of x (flatten into a disc or slab) |
| bands | bands [t:colour …] | — | hard colour bands from height fraction t up: [.3:cream .8:cherry] |
| stripes | colours [a b …] | — | colours cycled round the panels: [cherry white] |
| panels | integer 0–64 | 0 | angular panels with crisp edges (stripes, a pyramid with segs=panels) |
| phase | number | 0 | panel start angle, degrees |
| scallop | number 0–2 | 0 | fabric sag between panel edges, metres (canopies) |
| noise | number 0–0.3 | 0 | organic wobble, fraction of the radius |
| lean | x,y | 0,0 | top drifts x,z metres (quadratic, like a trunk) |
| bend | number -360–360 | 0 | curve toward +Z by this many degrees over the height |
| flare | number 0–2 | 0 | trunk flare at the base, fraction |
| open | none | top | bottom | both | none | leave an end open |
| cap | colour | — | colour of the flat end caps |
| segs | integer 3–64 | — | segments round (default from size) |
| rings | integer 1–64 | — | rings up (default from the profile) |
| prof | profile [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] |
| linear | flag | — | straight lines between stations (default smooth) |
cyl
a cylinder (or tapered drum) with rounded edges, base at the origin
| Key | Type | Default | What it does |
|---|---|---|---|
| h | number 0.001–200 | 1 | height, metres (grows up +Y from the origin) |
| r | number 0.0005–100 | 0.5 | radius, metres (prof radii are multiples of it) |
| sq | number 1.2–12 | 2 | cross-section squareness: 2 round, 4 rounded square, 8 box-like |
| depth | number 0.02–4 | 1 | z radius as a fraction of x (flatten into a disc or slab) |
| bands | bands [t:colour …] | — | hard colour bands from height fraction t up: [.3:cream .8:cherry] |
| stripes | colours [a b …] | — | colours cycled round the panels: [cherry white] |
| panels | integer 0–64 | 0 | angular panels with crisp edges (stripes, a pyramid with segs=panels) |
| phase | number | 0 | panel start angle, degrees |
| scallop | number 0–2 | 0 | fabric sag between panel edges, metres (canopies) |
| noise | number 0–0.3 | 0 | organic wobble, fraction of the radius |
| lean | x,y | 0,0 | top drifts x,z metres (quadratic, like a trunk) |
| bend | number -360–360 | 0 | curve toward +Z by this many degrees over the height |
| flare | number 0–2 | 0 | trunk flare at the base, fraction |
| open | none | top | bottom | both | none | leave an end open |
| cap | colour | — | colour of the flat end caps |
| segs | integer 3–64 | — | segments round (default from size) |
| rings | integer 1–64 | — | rings up (default from the profile) |
| r2 | number | — | top radius (default r) |
| round | number 0–50 | 0 | edge fillet radius, metres |
cone
a cone (or frustum with r2), base at the origin
| Key | Type | Default | What it does |
|---|---|---|---|
| h | number 0.001–200 | 1 | height, metres (grows up +Y from the origin) |
| r | number 0.0005–100 | 0.5 | radius, metres (prof radii are multiples of it) |
| sq | number 1.2–12 | 2 | cross-section squareness: 2 round, 4 rounded square, 8 box-like |
| depth | number 0.02–4 | 1 | z radius as a fraction of x (flatten into a disc or slab) |
| bands | bands [t:colour …] | — | hard colour bands from height fraction t up: [.3:cream .8:cherry] |
| stripes | colours [a b …] | — | colours cycled round the panels: [cherry white] |
| panels | integer 0–64 | 0 | angular panels with crisp edges (stripes, a pyramid with segs=panels) |
| phase | number | 0 | panel start angle, degrees |
| scallop | number 0–2 | 0 | fabric sag between panel edges, metres (canopies) |
| noise | number 0–0.3 | 0 | organic wobble, fraction of the radius |
| lean | x,y | 0,0 | top drifts x,z metres (quadratic, like a trunk) |
| bend | number -360–360 | 0 | curve toward +Z by this many degrees over the height |
| flare | number 0–2 | 0 | trunk flare at the base, fraction |
| open | none | top | bottom | both | none | leave an end open |
| cap | colour | — | colour of the flat end caps |
| segs | integer 3–64 | — | segments round (default from size) |
| rings | integer 1–64 | — | rings up (default from the profile) |
| r2 | number 0–100 | 0 | top radius |
ball
an ellipsoid centred on the origin
| Key | Type | Default | What it does |
|---|---|---|---|
| r | number or x,y,z | 0.5,0.5,0.5 | radius, or rx,ry,rz |
| under | colour | — | hard underside band below 30% down (foliage, bellies) |
| half | flag | — | top half only, flat bottom at the origin (domes, caps) |
| bands | bands [t:colour …] | — | hard colour bands from height fraction t up: [.3:cream .8:cherry] |
| stripes | colours [a b …] | — | colours cycled round the panels: [cherry white] |
| panels | integer 0–64 | 0 | angular panels with crisp edges (stripes, a pyramid with segs=panels) |
| phase | number | 0 | panel start angle, degrees |
| sq | number 1.2–12 | 2 | cross-section squareness: 2 round, 4 rounded square, 8 box-like |
| noise | number 0–0.3 | 0 | organic wobble, fraction of the radius |
| segs | integer 3–64 | — | segments round (default from size) |
| rings | integer 1–64 | — | rings up (default from the profile) |
puff
a foliage blob: ball with a darker underside band (color × .86) and wobble 0.06
| Key | Type | Default | What it does |
|---|---|---|---|
| r | number or x,y,z | 0.5,0.5,0.5 | radius, or rx,ry,rz |
| under | colour | — | underside colour (default color × 0.86) |
| noise | number 0–0.3 | 0.06 | wobble, fraction of rx |
| segs | integer 3–64 | — | segments round (default from size) |
| rings | integer 1–64 | — | rings up (default from the profile) |
box
a rounded box standing on the origin (true fillets, crisp colour cuts)
| Key | Type | Default | What it does |
|---|---|---|---|
| size | x,y,z | 1,1,1 | width (x), height (y), depth (z), metres |
| round | number | — | edge fillet radius, metres (default 12% of the smallest side) |
| bev | integer 1–3 | — | fillet smoothness 1..3 |
| bands | bands [t:colour …] | — | colour bands up the height: [.4:cream] |
| stripes | colours [a b …] | — | vertical stripes across x: [cherry white] |
| panels | integer 0–64 | 0 | stripe count across x |
| axis | x | z | x | stripes run across x or z |
tube
a round tube along points (in the part frame): handles, strings, tails, pipes
| Key | Type | Default | What it does |
|---|---|---|---|
| pts | points [(x,y,z) …] | — | points [0,0,0 0,1,0 .2,1.4,0] |
| r | number or x,y | 0.03,0.03 | radius, or start,end |
| smooth | flag | — | curve through the points (Catmull-Rom) |
| sides | integer 3–32 | — | sides |
rod
a straight bar from the origin to `to`, flat ends: poles, legs, rails, spokes
| Key | Type | Default | What it does |
|---|---|---|---|
| to | x,y,z | 0,1,0 | end point in the part frame |
| r | number or x,y | 0.03,0.03 | radius, or start,end |
| sides | integer 3–32 | — | sides |
| bands | bands [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)
| Key | Type | Default | What it does |
|---|---|---|---|
| len | number 0.001–50 | 0.4 | length, metres |
| r | number or x,y | 0.06,0.05 | radius, or top,bottom |
| bands | bands [t:colour …] | — | colour bands from the top (t 0) down (t 1): sleeves, socks |
| depth | number 0.1–4 | 1 | z radius as a fraction of x |
| segs | integer 3–64 | — | segments round |
torus
a ring lying flat (round Y), centred: rims, hoops, belts, lifebuoys (rot to stand it up)
| Key | Type | Default | What it does |
|---|---|---|---|
| R | number 0.001–100 | 0.5 | ring radius, metres |
| r | number 0.0005–50 | 0.05 | tube radius, metres |
| arc | number 1–360 | 360 | degrees of ring, centred on +Z (360 = closed) |
| segs | integer 3–128 | — | segments round the ring |
| sides | integer 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
| Key | Type | Default | What it does |
|---|---|---|---|
| pts | points [(x,y) …] | — | outline points [-.5,0 .5,0 0,1] |
| t | number 0.001–20 | 0.05 | thickness, metres |
| round | number | — | rim rounding, metres (≤ t/2) |
| edge | colour | — | rim colour (a trim band round the outline) |
wheel
a chunky wheel on an X axle, centred: tyre, hub and cap
| Key | Type | Default | What it does |
|---|---|---|---|
| r | number 0.01–20 | 0.3 | radius, metres |
| w | number 0.005–10 | 0.15 | width, metres |
| tyre | colour | — | tyre colour |
| hub | colour | — | hub colour |
| hubR | number 0.1–0.95 | 0.5 | hub radius, fraction of r |
face
a house face (unlit, never inked) on the parent surface: eyes, mouth, blush, brows
| Key | Type | Default | What it does |
|---|---|---|---|
| eyes | round | dot | happy | sleepy | none | round | eye style: round = big open eye, iris + pupil + shine; dot = a shiny bead; happy = closed ^ ^ arcs; sleepy = closed arcs |
| lid | number 0–1 | 0 | round eyes: upper lid, 0 = wide open and bright, .3 = calm, .5 = sleepy or bored, .7 = grumpy, 1 = shut |
| mouth | smile | grin | fang | open | flat | cat | none | smile | mouth 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 |
| size | number 0.03–0.6 | 0.16 | eye height, fraction of the head radius |
| spacing | number 4–80 | 22 | eye spacing, degrees either side of the front |
| eyeY | number -60–60 | 8 | eye elevation, degrees |
| mouthY | number -80–40 | -22 | mouth elevation, degrees |
| mouthW | number 0.05–1.2 | 0.4 | mouth width, fraction of the head radius |
| iris | colour | hairBrown | iris colour |
| skin | colour | — | the head colour the eye whites and blush lean toward (default the parent colour) |
| blush | flag | — | cheek blush (a multiply of the skin, never lighter) |
| brows | colour | — | brow colour (none when absent) |
Common keys
Every part takes these: placement, copies, rig and look.
| Key | Type | Default | What it does |
|---|---|---|---|
| on | name | — | parent part: this part rides it (its frame, bone, copies) |
| at | x,y,z | 0,0,0 | position in the parent frame; or an anchor of the parent (top, front, …) plus an offset: at=top+(0,.1,0) |
| surf | x,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 |
| lift | number | 0 | with surf: push out along the surface normal, metres (negative sinks in) |
| decal | flag | — | with surf: lie ON the surface (+Z out) instead of sticking out of it |
| upright | flag | — | with surf: keep the parent axes, take only the position (puffs, fruit, stones) |
| rot | x,y,z | 0,0,0 | rotation degrees x,y,z (yaw first, then pitch, then roll) |
| yaw | number | 0 | turn about Y, degrees |
| tilt | number | 0 | lean forward about X, degrees |
| roll | number | 0 | roll about Z, degrees |
| scale | number or x,y,z | 1,1,1 | scale (one number or x,y,z); children scale with it |
| color | colour | blossomWhite | main colour |
| ink | full | thin | none | glow | full | outline: full, thin (half), none (no line), glow (unlit, lined) |
| joint | flag | — | this part is a bone: it and its children can move (see anim) |
| mirror | flag | — | add a twin mirrored across the parent X = 0 (ears, eyes, legs, wheels); twins share their draws |
| x | integer 0–64 | 1 | copies (x3, x2..5 or x=3) |
| ring | number 0–180 | 0 | copies spread round the parent Y axis; the value is a seeded jitter in degrees |
| ring0 | number | 0 | start angle of a ring, degrees |
| row | x,y,z | — | copies in a centred row, this far apart |
| chain | x,y,z | — | copies in a chain: each one rides the last, this far on (with its rot): tails, garlands |
| if | number | 1 | include only when non-zero (chance(.5), form==tall) |
| detail | number 0.25–3 | 1 | tessellation multiplier |
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
| Preset | Channel | Wave | Amp | Hz | Twin | Use |
|---|---|---|---|---|---|---|
gait | rx | sin | 22 | 0.9 | 0.5 | legs or arms that swing in turn (mirror twins alternate) |
sway | rz | sin | 4 | 0.35 | 0 | a slow side-to-side lean (trees, signs, idle bodies) |
bob | py | sin | 0.05 | 0.8 | 0 | up and down (floating things, riders) |
bounce | py | bounce | 0.06 | 1.2 | 0 | hops that touch down (springs, happy idles) |
wag | ry | sin | 25 | 2 | 0 | a quick side-to-side (tails) |
flap | rz | sin | 35 | 2.5 | 0 | wings and fins (twins mirror on their own) |
nod | rx | sin | 8 | 0.5 | 0 | a head that nods |
spin | ry | spin | 0 | 0.25 | 0 | turns round Y forever (wheels need rot to spin on X) |
breathe | s | sin | 0.03 | 0.3 | 0 | a gentle swell (bodies, chests) |
Keys
| Key | Type | Default | What it does |
|---|---|---|---|
| amp | number | 10 | amplitude: degrees for rx/ry/rz, metres for px/py/pz, a fraction for s (scale) |
| hz | number 0–20 | 0.5 | cycles per second |
| phase | number | 0 | phase offset, cycles (with once: a delay, cycles) |
| stagger | number | 0 | extra phase per copy, cycles (waves along chains and rings) |
| twin | number | 0 | extra phase for the mirror twin, cycles (.5 = legs that alternate) |
| keys | keys [t:v …] | — | with the keys wave: values at cycle times, eased between: [0:0 .3:40 .7:40 1:0] |
| once | flag | — | 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
| Type | Particles | Hz | Speed | Gravity | Colours | Ink | Use |
|---|---|---|---|---|---|---|---|
jet | 22 | 0.8 | 3 | 9.8 | waterLightwater | thin | a fountain jet: a steady arc of water blobs (aim dir, set speed for the height) |
splash | 10 | 1.4 | 1.3 | 9.8 | foamwaterLight | thin | droplets bursting up and out where water lands |
puff | 5 | 0.45 | 0.45 | -0.25 | whitecream | thin | soft round puffs rising and swelling (chimneys, steam, breath) |
smoke | 7 | 0.35 | 0.35 | -0.2 | concretegreystone | thin | grey smoke billowing up (fires, exhausts, a dragon nostril) |
sparkle | 8 | 0.9 | 0 | 0 | sunflowerwhite | glow | little stars popping in and out round a point (magic, treasure, a fairy) |
Keys
| Key | Type | Default | What it does |
|---|---|---|---|
| on | name | — | the part it rides (required); one emitter per copy of it |
| at | x,y,z | 0,0,0 | emitter position in the parent frame, or an anchor of it plus an offset (at=top+(0,.02,0)) |
| dir | x,y,z | 0,1,0 | launch direction in the parent frame |
| n | integer 1–64 | — | particles alive at once |
| hz | number 0.05–20 | — | lives per second (1/hz = a particle lifetime, seconds) |
| speed | number 0–40 | — | launch speed, metres a second |
| spread | number 0–180 | — | cone half-angle, degrees (sparkle: the radius it scatters in, metres) |
| gravity | number -40–40 | — | fall, metres a second squared (negative rises: smoke) |
| size | number 0.002–5 | — | particle radius at birth, metres |
| grow | number 0–10 | — | radius at death, a multiple of size |
| color | colour | — | colour at birth |
| color2 | colour | — | colour at death (eased toward over the life) |
| ink | full | 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.
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.
| Complexity | Shapes | Triangles | Draw calls |
|---|---|---|---|
| c1 | 16 | 1,500 | 2 |
| c2 | 30 | 3,200 | 2 |
| c3 | 45 | 4,500 | 3 |
| c4 | 70 | 6,000 | 4 |
| c5 | 100 | 8,000 | 4 |
| c6 | 140 | 10,000 | 5 |
| c7 | 200 | 15,000 | 5 |
| c8 | 300 | 22,000 | 6 |
| c9 | 420 | 32,000 | 7 |
| c10 | 640 | 48,000 | 8 |
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). It follows the house face rules on every skin and fur colour. 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).
| Key | Type | Default | What it does |
|---|---|---|---|
| eyes | round | dot | happy | sleepy | none | round | eye style: round = big open eye, iris + pupil + shine; dot = a shiny bead; happy = closed ^ ^ arcs; sleepy = closed arcs |
| lid | number 0–1 | 0 | round eyes: upper lid, 0 = wide open and bright, .3 = calm, .5 = sleepy or bored, .7 = grumpy, 1 = shut |
| mouth | smile | grin | fang | open | flat | cat | none | smile | mouth 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 |
| size | number 0.03–0.6 | 0.16 | eye height, fraction of the head radius |
| spacing | number 4–80 | 22 | eye spacing, degrees either side of the front |
| eyeY | number -60–60 | 8 | eye elevation, degrees |
| mouthY | number -80–40 | -22 | mouth elevation, degrees |
| mouthW | number 0.05–1.2 | 0.4 | mouth width, fraction of the head radius |
| iris | colour | hairBrown | iris colour |
| skin | colour | — | the head colour the eye whites and blush lean toward (default the parent colour) |
| blush | flag | — | cheek blush (a multiply of the skin, never lighter) |
| brows | colour | — | brow colour (none when absent) |
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.
Templates
| Template | Ground | Size | Mood | What it is |
|---|---|---|---|---|
town | disc | 36 m | day | open grass patch for streets, houses and a square; trees ring the edge (size 36, use about -30..30) |
forest | disc | 22 m | day | a round clearing in a thick wood (size 22, use about -18..18) |
beach | disc | 30 m | day | sand with the sea on the far (-z) side: keep things at z > -0.3*size (size 30) |
arena | disc | 24 m | day | a round sand battle floor (r = 0.7*size) inside grass, stones and trees around (size 24) |
plaza | disc | 24 m | day | a paved round square (r = 0.55*size) in a park ring (size 24) |
tabletop | base | 10 m | day | a small round toy base you orbit (size 10, use about -8..8) |
retro | square | 30 m | day | a 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) |
carnival | disc | 34 m | night | a night fairground: a dirt circle (r = 0.62*size) in grass with trees around; light it with light lines (size 34) |
mountain | disc | 40 m | day | a grassy valley floor ringed by snowy peaks (size 40, use about -36..36) |
interior | plinth | 24 m | day | a square floor plate for rooms, halls and storeys, seen as a cutaway (size 24, use about -22..22) |
dungeon | plinth | 30 m | dark | a dark square stone plate for rooms and halls, lit only by light lines (size 30, use about -28..28) |
Layout verbs
| Verb | Form | Notes |
|---|---|---|
lots | lots <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 |
place | place <alias> at <x> <z> [face <deg>|face <x> <z>] | |
row | row <list> from <x z> to <x z> [gap=<m>] [count=<n>] [face …] | spread evenly along a line |
grid | grid <list> at <x z> <cols>x<rows> [gap=1] | |
ring | ring <list> at <x z> r=<r> [count=<n>] [face in|out|<deg>] | (faces in by default) |
scatter | scatter <list> in <area> [count=<n>] [spacing=1] | random, never on paths, buildings or water |
cluster | cluster <list> at <x z> [r=3] [count=<n>] [spacing=0.3] | a tight natural group |
along | along <path> <list> [every=6] [side=left|right|both] [offset=0.6] e.g. lamps, benches, hedges by a road | e.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.
fox-cub.cel
Open in PlaygroundA critter: a jointed body on mirrored legs, a face, a chain tail, idle motion and a walk state
snail-van.cel
Open in PlaygroundA vehicle: boxes with rounded edges, glass set proud of the body, glow lamps, a face, a spiral tube, wheels, a once state
tree-cloud.cel
Open in PlaygroundA plant: genes for every proportion, weighted colour picks, copies on a ring, puffs stuck to a surface
fountain.cel
Open in PlaygroundCel FX: water jets from a nozzle and from four aimed spouts (one fx line each), a splash, a state-only burst