Creatures › Geno
Geno
The GenoCode logo come to life: the G's chain of balls, each a little smaller than the last and a little further round the colour wheel. Its form genes bend the chain into other shapes: a sea turtle, whose shell, head, eyes, flippers and tail are each one of the G's balls, swelling and stretching into place as the rest spiral over the shell, and a double helix with rungs in four colours. Morph it through its variants, or breed it for hybrids. It has a dance of its own.
26 genes · 2 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 Geno mutates, breeds and morphs.
| Gene | What it does | Range | Value |
|---|---|---|---|
logo | how much the chain keeps the shape of the G | 0 to 1 | 1 |
sea_turtle | how much it curls into a turtle | 0 to 1 | 0 |
helix | how much it twists into a double helix | 0 to 1 | 0 |
beads | how many balls are in the chain | 12 to 40, steps of 1 | 18 |
big | the first ball's radius | 0.5 to 2.5 | 1.35 |
shrink | the last ball's radius compared with the first's | 0.2 to 1 | 0.41 |
start | the first ball's colour | any hue | hsv(195, 0.75, 1, 1) |
turn | how far round the colour wheel the chain goes | -360 to 360 | 140 |
gloss | 0 to 1 | 0.6 | |
focus | 0 to 1 | 0.5 | |
breathe | how much the balls swell and shrink as time goes by | 0 to 0.3 | 0.06 |
pulse | how much they swell with the bass | 0 to 1 | 0.3 |
shell | any hue | hsv(272, 0.5, 0.34, 1) | |
skin | any hue | hsv(168, 0.45, 0.8, 1) | |
paddle | how far the flippers sweep | 0 to 60 | 25 |
pace | flipper strokes a second | 0 to 2 | 0.4 |
twists | how many times the helix turns along its span | 0.5 to 4 | 1.25 |
spin | how fast the helix turns, in degrees a second | -180 to 180 | 40 |
base_a | any hue | hsv(195, 0.75, 1, 1) | |
base_t | any hue | hsv(335, 0.75, 1, 1) | |
base_g | any hue | hsv(265, 0.75, 1, 1) | |
base_c | any hue | hsv(45, 0.75, 1, 1) | |
background.top | any hue | hsv(250, 0.55, 0.18, 1) | |
background.bottom | any hue | hsv(290, 0.45, 0.36, 1) | |
dance.drive | how many forms a second the music carries it through | 0.1 to 2 | 0.5 |
dance.whirl | how fast it spins at its loudest, in degrees a second | 30 to 360 | 120 |
The code
creature Geno
// The GenoCode logo come to life: the G's chain of balls, each a little smaller than the last and a
// little further round the colour wheel. Its form genes bend the chain into other shapes: a sea
// turtle, whose shell, head, eyes, flippers and tail are each one of the G's balls, swelling and
// stretching into place as the rest spiral over the shell, and a double helix with rungs in four
// colours. Morph it through its variants, or breed it for hybrids. It has a dance of its own.
gene logo = 1 in 0..1 // how much the chain keeps the shape of the G
gene sea_turtle = 0 in 0..1 // how much it curls into a turtle
gene helix = 0 in 0..1 // how much it twists into a double helix
gene beads = 18 in 12..40 step 1 // how many balls are in the chain
gene big = 1.35 in 0.5..2.5 // the first ball's radius
gene shrink = 0.41 in 0.2..1 // the last ball's radius compared with the first's
gene start = hsv(195, 0.75, 1) in hsv(0, 0, 0)..hsv(360, 1, 1) // the first ball's colour
gene turn = 140 in -360..360 // how far round the colour wheel the chain goes
gene gloss = 0.6 in 0..1
gene focus = 0.5 in 0..1
gene breathe = 0.06 in 0..0.3 // how much the balls swell and shrink as time goes by
gene pulse = 0.3 in 0..1 // how much they swell with the bass
gene shell = hsv(272, 0.5, 0.34) in hsv(0, 0, 0)..hsv(360, 1, 1)
gene skin = hsv(168, 0.45, 0.8) in hsv(0, 0, 0)..hsv(360, 1, 1)
gene paddle = 25 in 0..60 // how far the flippers sweep
gene pace = 0.4 in 0..2 // flipper strokes a second
gene twists = 1.25 in 0.5..4 // how many times the helix turns along its span
gene spin = 40 in -180..180 // how fast the helix turns, in degrees a second
gene base_a = hsv(195, 0.75, 1) in hsv(0, 0, 0)..hsv(360, 1, 1)
gene base_t = hsv(335, 0.75, 1) in hsv(0, 0, 0)..hsv(360, 1, 1)
gene base_g = hsv(265, 0.75, 1) in hsv(0, 0, 0)..hsv(360, 1, 1)
gene base_c = hsv(45, 0.75, 1) in hsv(0, 0, 0)..hsv(360, 1, 1)
// How much of each form the creature is, out of 1.
let total = max(logo + sea_turtle + helix, 0.001)
let wl = logo / total
let wt = sea_turtle / total
let wh = helix / total
shine gloss
sharpness focus
chain
// The balls, each where the forms put it, mixed by how much of each form the creature is. Nine of
// them become the turtle's shell, head, eyes, flippers and tail; the rest spiral over its shell.
part chain {
let n = round(beads)
let scale = 18 / n
repeat n as k {
let u = k / max(n - 1, 1)
let role = role_of(k, n)
let v = (k - parts_before(k, n)) / max(n - 10, 1)
let p = wl * on_g(u) + wt * on_turtle(role, v) + wh * on_helix(u)
let swell = 1 + breathe * (wave(time / 3 - u) - wave(-u)) + pulse * music.bass
let r = scale * big * swell * (wl * shrink ^ u + wh * 0.6)
let r_turtle = scale * big * swell * 0.7 * shrink ^ (0.4 * v)
let own = hsv(start.hue + turn * u, start.sat, start.val)
colour mix(own, turtle_colour(role, own), wt)
branch {
move p
if role == 6 {
pitch 90 * wt
} else if role >= 4 {
turn_flipper(role)
}
lay { grow mix(vec(2 * r, 2 * r, 2 * r), turtle_size(role, r_turtle), wt) }
}
if wh > 0 {
branch {
move (p.x, -p.y, -p.z)
lay { grow 2 * r * wh }
}
branch {
rung(k, p, 0.5 * r * wh)
}
}
}
}
// The G: 315° round a circle from its top right, then the bar in towards the middle. The balls
// are spaced by their size, as in the logo.
function on_g(u) {
let radius = 3.9
let arc = radius * radians(315)
let span = arc + 2.7
let s = span * u
if shrink < 0.99 {
s = span * (1 - shrink ^ u) / (1 - shrink)
}
if s <= arc {
let a = 45 + 315 * s / arc
return (radius * cos(a), radius * sin(a), 0)
}
return (radius - (s - arc), 0, 0)
}
// The ball nearest the point `a` degrees round the G (on_g backwards).
function ball_at(a, n) {
let radius = 3.9
let arc = radius * radians(315)
let span = arc + 2.7
let s = arc * (a - 45) / 315
let u = s / span
if shrink < 0.99 {
u = ln(1 - s * (1 - shrink) / span) / ln(shrink)
}
return clamp(round(u * (n - 1)), 0, n - 1)
}
// Which ball becomes turtle part `i`, the parts in order along the G: 0 the shell (the first,
// biggest ball), 1 the right eye, 2 the head (the top of the G), 3 the left eye, 4 the front left
// flipper, 5 the back left flipper, 6 the tail (the bottom of the G), 7 the back right flipper and
// 8 the front right flipper. Each takes the ball nearest its place, or the next one free.
function part_ball(i, n) {
if i == 0 {
return 0
}
let target = ball_at(360, n)
if i <= 3 {
target = ball_at(100, n) + i - 2
} else if i == 4 {
target = ball_at(155, n)
} else if i == 5 {
target = ball_at(215, n)
} else if i == 6 {
target = ball_at(270, n)
} else if i == 7 {
target = ball_at(325, n)
}
return max(target, part_ball(i - 1, n) + 1)
}
// The turtle part ball `k` becomes, or -1 for a ball of the shell's spiral.
function role_of(k, n) {
let role = -1
repeat 9 as i {
if part_ball(i, n) == k {
role = i
}
}
return role
}
// How many of the balls before ball `k` become turtle parts.
function parts_before(k, n) {
let count = 0
repeat 9 as i {
if part_ball(i, n) < k {
count += 1
}
}
return count
}
// Where each part of the turtle is. `v` runs along the shell's balls: one on the crown, the rest
// in a ring that spirals out round it the way the G winds.
function on_turtle(role, v) {
let sway = 0.3 * wave(time * pace / 2)
if role == 0 {
return (0, 0, -0.1)
} else if role == 2 {
return (sway, 5.3, 0)
} else if role == 1 or role == 3 {
return (sway + 0.5 * (2 - role), 5.8, 0.55)
} else if role == 6 {
return (0, -5.2, -0.2)
} else if role >= 4 {
let a = flipper_angle(role)
let side = 1
if role < 6 {
side = -1
}
let anchor = (2.9 * side, 2.6, -0.2)
let reach = 1.6
if role == 5 or role == 7 {
anchor = (2.4 * side, -3.3, -0.2)
reach = 1
}
return anchor + reach * vec(cos(a), sin(a), 0)
}
let lat = 0
if v > 0 {
lat = 38 + 30 * v
}
let lon = 90 + 320 * v
return (3.75 * sin(lat) * cos(lon), 4.5 * sin(lat) * sin(lon), 1.9 * cos(lat))
}
// Turns a flipper out of the ball it grows from: to the right, or to the left for the left
// flippers, then round to its angle.
part turn_flipper(role) {
let a = flipper_angle(role)
if role < 6 {
yaw -90 * wt
a = 180 - a
} else {
yaw 90 * wt
}
pitch -a * wt
}
// Which way a flipper or the tail points, in degrees round from the right.
function flipper_angle(role) {
let fore = 40 + paddle * wave(time * pace)
let hind = -35 - 0.5 * paddle * wave(time * pace + 0.25)
if role == 4 {
return 180 - fore
} else if role == 5 {
return 180 - hind
} else if role == 7 {
return hind
} else if role == 8 {
return fore
}
return -90
}
// The size of each part of the turtle, across, up and along the way it points.
function turtle_size(role, r) {
if role == 0 {
return (7.5, 9, 3.8)
} else if role == 2 {
return (1.9, 2.4, 1.5)
} else if role == 1 or role == 3 {
return (0.4, 0.4, 0.4)
} else if role == 4 or role == 8 {
return (0.35, 1.1, 3.8)
} else if role == 5 or role == 7 {
return (0.3, 0.9, 2.3)
} else if role == 6 {
return (0.35, 0.6, 1.6)
}
return vec(2 * r, 2 * r, 2 * r)
}
function turtle_colour(role, own) {
if role == 0 {
return shell
} else if role == 1 or role == 3 {
return black
} else if role >= 2 {
return skin
}
return own
}
// One strand of the helix, lying along x. The other strand is this one turned half way round.
function on_helix(u) {
let a = 360 * twists * u + spin * time
return ((u - 0.5) * 12, 2.3 * cos(a), 2.3 * sin(a))
}
// A rung joining a ball to its partner on the other strand: a pair of bases, A with T or G with C.
part rung(k, p, thick) {
let reach = sqrt(p.y ^ 2 + p.z ^ 2)
let near = base_a
let far = base_t
if noise(k * 1.7 + 0.3) > 0 {
near = base_g
far = base_c
}
if noise(k * 2.3 + 5.1) > 0 {
let swap = near
near = far
far = swap
}
shape tube
move (p.x, 0, 0)
pitch atan2(p.z, p.y) - 90
branch {
colour near
forward reach / 2
lay { grow (thick, thick, reach) }
}
colour far
back reach / 2
lay { grow (thick, thick, reach) }
}
background {
gene top = hsv(250, 0.55, 0.18) in hsv(0, 0, 0)..hsv(360, 1, 1)
gene bottom = hsv(290, 0.45, 0.36) in hsv(0, 0, 0)..hsv(360, 1, 1)
fill gradient(bottom, top)
}
// Geno's own dance: the music carries it slowly round its forms, so the G, the turtle and the
// helix each get seen; the kicks pull it nearer and turn it; drops in the highs send it back the
// way it came; and now and then the snares turn it face-on, to spin flat like the logo.
dance {
gene drive = 0.5 in 0.1..2 // how many forms a second the music carries it through
gene whirl = 120 in 30..360 // how fast it spins at its loudest, in degrees a second
morph follows music.level speed drive settle 3
zoom follows music.bass_hit amount 0.4 settle 8
spin follows music.bass from 20 to whirl smooth 1
turn on music.bass_hit rises by 0.5
reverse on music.high drops by 0.6 on 16 off 16
flat on music.mid_hit drops by 0.7 on 16 off 48
}
variant Turtle { logo = 0; sea_turtle = 1; start = hsv(170, 0.7, 0.95); turn = 120 }
variant Helix { logo = 0; helix = 1; big = 0.9 }