GenoCode Getting startedThe languageCreatures Open the app

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.

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

Open in GenoCodeDownload Geno.genie

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.

Geno, Turtle
Turtle
Geno, Helix
Helix

Genes

The values that change when Geno mutates, breeds and morphs.

GeneWhat it doesRangeValue
logohow much the chain keeps the shape of the G0 to 11
sea_turtlehow much it curls into a turtle0 to 10
helixhow much it twists into a double helix0 to 10
beadshow many balls are in the chain12 to 40, steps of 118
bigthe first ball's radius0.5 to 2.51.35
shrinkthe last ball's radius compared with the first's0.2 to 10.41
startthe first ball's colourany huehsv(195, 0.75, 1, 1)
turnhow far round the colour wheel the chain goes-360 to 360140
gloss0 to 10.6
focus0 to 10.5
breathehow much the balls swell and shrink as time goes by0 to 0.30.06
pulsehow much they swell with the bass0 to 10.3
shellany huehsv(272, 0.5, 0.34, 1)
skinany huehsv(168, 0.45, 0.8, 1)
paddlehow far the flippers sweep0 to 6025
paceflipper strokes a second0 to 20.4
twistshow many times the helix turns along its span0.5 to 41.25
spinhow fast the helix turns, in degrees a second-180 to 18040
base_aany huehsv(195, 0.75, 1, 1)
base_tany huehsv(335, 0.75, 1, 1)
base_gany huehsv(265, 0.75, 1, 1)
base_cany huehsv(45, 0.75, 1, 1)
background.topany huehsv(250, 0.55, 0.18, 1)
background.bottomany huehsv(290, 0.45, 0.36, 1)
dance.drivehow many forms a second the music carries it through0.1 to 20.5
dance.whirlhow fast it spins at its loudest, in degrees a second30 to 360120

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 }

← GenieAll creaturesGreenbay →