DISK 17 / LENIA

life that is not made of squares: every point holds a number between nothing and full, and at each step it looks at a soft ring of its neighbours and grows if the ring is just full enough, and fades if it is too empty or too crowded. blobs form, spread and split, and knot themselves into worms that shift about as if they were alive

a floppy disk out of the vending machine, run by pino on the computer at the internet cafe. Bert Wang-Chak Chan, Lenia, 2018; written for the cafe.

function setup(ctx, W, H) {
var k = { n: 64, R: 8, mu: 0.15, sigma: 0.015, dt: 0.1 }
/*TWEAK*/
var n = k.n, ker = [], sum = 0
for (var dy = -k.R; dy <= k.R; dy++) for (var dx = -k.R; dx <= k.R; dx++) {
  var r = Math.sqrt(dx * dx + dy * dy) / k.R
  if (r <= 0 || r >= 1) continue
  var w = Math.exp(4 - 1 / (r * (1 - r)))
  ker.push([dx, dy, w]); sum += w
}
for (var i = 0; i < ker.length; i++) ker[i][2] /= sum
function seed(a) {
  for (var j = 0; j < a.length; j++) a[j] = 0
  // a few patches of noise, and whatever lives through the first second is what you see
  for (var p = 0; p < 5; p++) {
    var ox = Math.floor(Math.random() * n), oy = Math.floor(Math.random() * n)
    for (var y = 0; y < 18; y++) for (var x = 0; x < 18; x++) a[((oy + y) % n) * n + (ox + x) % n] = Math.random() * 1.2 > 0.35 ? Math.random() : 0
  }
}
var a = new Float32Array(n * n)
seed(a)
var c = document.createElement('canvas')
c.width = n
c.height = n
var cx = c.getContext('2d')
return { k: k, n: n, ker: ker, a: a, b: new Float32Array(n * n), seed: seed, c: c, cx: cx, img: cx.createImageData(n, n) }
}
function update(state, t, W, H) {
var s = state, n = s.n, a = s.a, b = s.b, ker = s.ker, k = s.k, mass = 0
for (var y = 0; y < n; y++) for (var x = 0; x < n; x++) {
  var u = 0
  for (var i = 0; i < ker.length; i++) { var q = ker[i]; u += a[((y + q[1] + n) % n) * n + (x + q[0] + n) % n] * q[2] }
  var g = 2 * Math.exp(-((u - k.mu) * (u - k.mu)) / (2 * k.sigma * k.sigma)) - 1
  var v = a[y * n + x] + k.dt * g
  v = v < 0 ? 0 : v > 1 ? 1 : v
  b[y * n + x] = v
  mass += v
}
s.a = b
s.b = a
if (mass < 1) s.seed(s.a)
}
function render(ctx, state, t, W, H) {
var s = state, n = s.n, a = s.a, d = s.img.data
for (var i = 0; i < n * n; i++) {
  var v = a[i]
  d[i * 4] = 255 * Math.min(1, v * 2.2 - 0.6 < 0 ? 0 : v * 2.2 - 0.6) + 10
  d[i * 4 + 1] = 40 + 200 * v
  d[i * 4 + 2] = 70 + 150 * Math.sqrt(v)
  d[i * 4 + 3] = 255
}
s.cx.putImageData(s.img, 0, 0)
ctx.imageSmoothingEnabled = true
ctx.drawImage(s.c, 0, 0, W, H)
}

more of these