if you can comprehend what i've started here, this is your chance to express your aesthetic in a new branch of automata

Code:
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define OP_GT   (0)
#define OP_GTE  (1)
#define OP_LT   (2)
#define OP_LTE  (3)

typedef struct grid grid_t;
typedef struct rule rule_t;
typedef struct page page_t;
typedef struct ofst ofst_t;

struct grid
{
  uint32_t d;
  uint32_t *m;
};

struct ofst
{
  int8_t x;
  int8_t y;
};

struct rule
{
  uint8_t f   : 1;
  uint8_t op  : 2;
  uint8_t x   : 3;
  uint8_t z   : 2; // not used
};

struct page
{
  rule_t  r;
  uint8_t n;
};


void wcell(grid_t *g, uint32_t x, uint32_t y, uint8_t v)
{
  uint32_t d = g->d;
  if (x >= d || y >= d)
    return;
  g[x + d * y] = v;
}


uint8_t rcell(grid_t *g, uint32_t x, uint32_t y)
{
  uint32_t d = g->d;
  if (x >= d || y >= d)
    return 0;
  return g[x + d * y];
}


void info(page_t *p, grid_t *g, uint32_t x, uint32_t y)
{
  offset_t o[8] = {
    { .x = -1, .y = -1 },
    { .x =  0, .y = -1 },
    { .x =  1, .y = -1 },
    { .x =  1, .y =  0 },
    { .x =  1, .y =  1 },
    { .x =  0, .y =  1 },
    { .x = -1, .y =  1 },
    { .x = -1, .y =  0 },
  };
  uint8_t c;

  // 0 1 2
  // 7   3
  // 6 5 4

  memset(p, 0, sizeof(page_t));
  for (i = 0; i < 8; i++) {
    c = rcell(g, x + o[i].x, y + o[i].y);
    p.n += c;
    p.r = (p.r << 1) | c;
  }
}


void next_step(grid_t *n, grid_t *g, uint32_t x, uint32_t y)
{
  page_t p;
  info(&p, g, x, y);
  switch (p.r.op)
  {
    case OP_GT:  if (p.r.x > p.n)  wcell(n, x, y, p.r.f); return;
    case OP_GTE: if (p.r.x >= p.n) wcell(n, x, y, p.r.f); return;
    case OP_LT:  if (p.r.x < p.n)  wcell(n, x, y, p.r.f); return;
    case OP_LTE: if (p.r.x <= p.n) wcell(n, x, y, p.r.f); return;
  }
  wcell(n, x, y, rcell(g, x, y));
}


void next_grid(grid_t *n, grid_t *g)
{
  uint32_t x, y, d;
  d = g->d;
  for (x = 0; x < d; x++)
    for (y = 0; y < d; y++)
      next_step(n, g, x, y);
}


int main (int argc, char **argv)
{
  grid_t a, b, *v, *w;

  v = &a; w = &b;
  memset(v, 0, sizeof(grid_t));
  memset(w, 0, sizeof(grid_t));

  // load v

  for (;;) {
    draw(v);
    next_grid(w, v);
    if (v == &a) { v = &b; w = &a; }
    else         { v = &a; w = &b; }
  }

  return 0;
}
it doesn't compile yet. i don't usually need the compiler until the very end. just fill in the blanks and don't talk shit