Creatures › Tree
Tree
A tree's whole life. From a seed, roots reach down and a shoot rises; it forks again and again, each limb shorter than the one it grows from; leaves open at the tips of the twigs, and last of all flowers bloom among them. Its age runs that life, so it morphs smoothly from a seed to a tree in bloom and, round its variants, back to a seed. The leaves run round the colour wheel across the crown, and the branches sway in the wind as time goes by. It has a calm dance of its own. Inspired by Tree, a Fantastic Avian Creatures design.
21 genes · 3 variants · moves by itself · has a dance of its own
Its family
Each one is the same program with different genes. In the app, Morph glides from one to the next, and Breed starts from them.



Genes
The values that change when Tree mutates, breeds and morphs.
| Gene | What it does | Range | Value |
|---|---|---|---|
age | how far it has grown: 0 a seed, 0.5 bare branches, 0.75 in leaf, 1 in bloom | 0 to 1 | 1 |
depth | how many times the limbs fork; a fraction grows the last ones part way | 2 to 6 | 5 |
wind | how much the branches sway as time goes by | 0 to 1 | 0.3 |
bark | any hue | hsv(28.8, 0.6, 0.5, 1) | |
root_count | how many roots; a fraction grows the last one part way | 3 to 8 | 5 |
root_span | how long they are | 1 to 4 | 2.2 |
root_droop | how steeply they reach down | 20 to 80 | 55 |
seed.husk | any hue | hsv(30, 0.7, 0.45, 1) | |
limb.reach | 1 to 5 | 3 | |
limb.thick | 0.15 to 1 | 0.5 | |
limb.spread | how far each fork leans out from its limb | 5.7 to 80.2 | 34.4 |
limb.shrink | each limb's size compared with the one it grows from | 0.5 to 0.9 | 0.72 |
limb.forks | how many forks; a fraction grows the last one part way | 2 to 4 | 3 |
limb.turn | how far round the forks turn | 0 to 114.6 | 22.9 |
limb.leaf | the first leaf's colour | any hue | hsv(108, 0.85, 0.95, 1) |
limb.rainbow | how far round the colour wheel the leaves go | 0 to 360 | 300 |
flower.petals | 3 to 8, steps of 1 | 5 | |
flower.blossom | any hue | hsv(330, 0.35, 1, 1) | |
flower.heart | any hue | hsv(48, 0.9, 1, 1) | |
dance.growth | how many trees a second the music grows it through | 0.1 to 1 | 0.3 |
dance.sway | how fast it turns at its loudest, in degrees a second | 10 to 120 | 40 |
The code
creature Tree
// A tree's whole life. From a seed, roots reach down and a shoot rises; it forks again and again,
// each limb shorter than the one it grows from; leaves open at the tips of the twigs, and last of
// all flowers bloom among them. Its age runs that life, so it morphs smoothly from a seed to a tree
// in bloom and, round its variants, back to a seed. The leaves run round the colour wheel across
// the crown, and the branches sway in the wind as time goes by. It has a calm dance of its own.
// Inspired by Tree, a Fantastic Avian Creatures design.
gene age = 1 in 0..1 // how far it has grown: 0 a seed, 0.5 bare branches, 0.75 in leaf, 1 in bloom
gene depth = 5 in 2..6 // how many times the limbs fork; a fraction grows the last ones part way
gene wind = 0.3 in 0..1 // how much the branches sway as time goes by
gene bark = hsv(28.8, 0.6, 0.5) in hsv(0, 0.2, 0.2)..hsv(360, 1, 1)
gene root_count = 5 in 3..8 // how many roots; a fraction grows the last one part way
gene root_span = 2.2 in 1..4 // how long they are
gene root_droop = 55 in 20..80 // how steeply they reach down
// The stages of its life, each running from 0 (not yet) to 1 (done).
let rooted = ease(age, 0, 0.3)
let sprouted = ease(age, 0.05, 0.3)
let grown = ease(age, 0.08, 0.62) * (depth + 1) // how many levels of limbs have grown, trunk first
let leafy = ease(age, 0.55, 0.8)
let blooming = ease(age, 0.82, 1)
pitch -90
back 4
seed
root_ring
limb(0, 1, 0, 1)
// Eases from 0 to 1 as x goes from `lo` to `hi`.
function ease(x, lo, hi) {
let t = clamp((x - lo) / (hi - lo), 0, 1)
return t * t * (3 - 2 * t)
}
// The seed it grows from, which shrinks away as the shoot rises out of it.
part seed {
gene husk = hsv(30, 0.7, 0.45) in hsv(0, 0.2, 0.2)..hsv(360, 1, 1)
let left = 1 - sprouted
if left > 0 {
shape ball
colour husk
lay { grow (0.9, 0.9, 1.3) * left }
}
}
// The roots: a ring of them reaching down and out, each forking once.
part root_ring {
repeat ceil(root_count) as i {
let share = min(1, root_count - i)
branch {
roll 360 * i / root_count
pitch 180 - root_droop
root(0, share)
}
}
}
// One root and the two it forks into, growing as the tree takes root.
part root(level, size) {
let ripe = ease(rooted * 2 - level, 0, 1) * size
if ripe > 0 {
shape tube
colour bark
texture pattern(cells, bark.hue, 12, analogous, satin)
let reach = root_span * ripe
branch {
forward reach / 2
lay { grow (0.35 * ripe, 0.35 * ripe, reach) }
}
forward reach
if level < 1 {
repeat 2 as i {
branch {
roll 180 * i + 40
pitch 30
root(level + 1, size * 0.7)
}
}
}
}
}
// One limb and everything that grows from it: level 0 is the trunk. Its leaves take the slice
// `first` to `first + width` of the colour wheel's turn, shared out between its forks.
part limb(level, size, first, width) {
gene reach = 3 in 1..5
gene thick = 0.5 in 0.15..1
gene spread = 34.4 in 5.7..80.2 // how far each fork leans out from its limb
gene shrink = 0.72 in 0.5..0.9 // each limb's size compared with the one it grows from
gene forks = 3 in 2..4 // how many forks; a fraction grows the last one part way
gene turn = 22.9 in 0..114.6 // how far round the forks turn
gene leaf = hsv(108, 0.85, 0.95) in hsv(0, 0.3, 0.4)..hsv(360, 1, 1) // the first leaf's colour
gene rainbow = 300 in 0..360 // how far round the colour wheel the leaves go
// How far this limb has grown, and how far the next ones have.
let ripe = clamp(grown - level, 0, 1)
let next = clamp(grown - level - 1, 0, 1)
grow size
// The wind bends every limb a little, so the twigs at the top move the most.
yaw wind * 4 * sin(time * 50 + level * 70 + first * 360)
shape tube
colour bark
texture pattern(cells, bark.hue, 12, analogous, satin)
let stretch = reach * ripe
branch {
forward stretch / 2
lay { grow (thick * (0.4 + 0.6 * ripe), thick * (0.4 + 0.6 * ripe), stretch) }
}
forward stretch
if next > 0 {
repeat ceil(forks) as i {
branch {
roll 360 * i / forks + turn
pitch spread
limb(level + 1, shrink * min(1, forks - i), first + width * i / forks, width / forks)
}
}
}
// A leaf at the tip, and later a flower at about every other one, while its twigs haven't grown;
// they give way as the twigs sprout, and the new tips take them up.
let tip = ripe * (1 - next)
if tip * leafy > 0 {
shape ball
texture none
colour hsv(leaf.hue + rainbow * (first + width / 2), leaf.sat, leaf.val)
lay { grow 1.2 * tip * leafy }
}
if tip * blooming > 0 and noise(first * 40) > 0 {
flower(tip * blooming)
}
}
// A flower opening at a twig's tip: a heart and a ring of petals that spread as it opens.
part flower(open) {
gene petals = 5 in 3..8 step 1
gene blossom = hsv(330, 0.35, 1) in hsv(0, 0, 0.6)..hsv(360, 1, 1)
gene heart = hsv(48, 0.9, 1) in hsv(0, 0, 0.6)..hsv(360, 1, 1)
texture none
forward 0.5
grow 2
shape ball
colour heart
lay { grow 0.45 * open }
colour blossom
repeat petals as i {
branch {
roll 360 * i / petals
pitch 75 * open
forward 0.4 * open
lay { grow (0.35, 0.15, 0.9) * open }
}
}
}
// The Tree's own dance, calm like a tree in the wind: the music slowly grows it through its kin,
// the bass makes it breathe nearer, and the kicks are gusts that swing it gently round to a new
// way. It never spins flat: a tree is best seen in the round.
dance {
gene growth = 0.3 in 0.1..1 // how many trees a second the music grows it through
gene sway = 40 in 10..120 // how fast it turns at its loudest, in degrees a second
morph follows music.level speed growth settle 4
zoom follows music.bass amount 0.3 settle 4
spin follows music.level from 8 to sway smooth 3
turn on music.bass_hit rises by 0.6
reverse on music.high drops by 0.5 on 8 off 8
}
variant Seed { age = 0.02 }
variant Sapling { age = 0.35 }
variant Leafy { age = 0.75 }