# Generations: Feed It Back

*Task 3 of 5 · [Cellular Automata](https://gpu.rocks/learn/cellular-automata-407c2c34.md) · GPU.js Learn*

One tick is a snapshot; a world is a movie. A kernel has no memory of the previous
frame — **time lives in JavaScript**. The result of a 2D kernel is an array of
rows, which is exactly the shape the kernel accepts as input, so
`current = await step(current)` is the whole time machine: output becomes input,
forever.

Your test subject is the **R-pentomino** — five innocent-looking cells that
erupt into chaos (on an infinite grid they don't settle down for 1,103 generations; Conway's
group tracked it by hand). You'll run six generations and log the population after each, so
you can watch the explosion begin.

## Figures

- **the kernel ticks; javascript turns the crank — output straight back in**

## Goal

**Goal:** restore the B3/S23 rule inside the kernel, then run 6
generations by feeding each output back in — logging
`'gen ' + g + ': ' + alive + ' alive'` after every step.

## Requirements

- Complete the kernel: the same B3/S23 rule you wrote last task
- Loop 6 times in plain JavaScript, reassigning: `current = await step(current)`
- After each step, total the live cells in plain JS (kernel output rows are ordinary arrays)
- Log each generation exactly as `'gen ' + g + ': ' + alive + ' alive'`, g from 1 to 6

## Hint 1 — the feed-back loop

`let current = world;` then

```js
for (let g = 1; g <= 6; g++) {
  current = await step(current);
  // …
}
```

No copying, no bookkeeping — the kernel's output is already a valid input.

## Hint 2 — counting the living

Inside the loop, after stepping: `let alive = 0;` and two nested
loops adding `current[y][x]`. Cells are 0 or 1, so the sum *is* the
population.

## Same idea elsewhere

The frame loop lives on the host everywhere: a CUDA fluid sim launches its kernel
thousands of times from an ordinary CPU `for` loop, and a Metal app encodes one
compute dispatch per frame — the GPU computes each tick, but the CPU decides that time
passes.

## Starter code

```js
// The kernel computes one tick. Time itself is a JavaScript loop:
// whatever comes out goes straight back in.
const gpu = new GPU({ mode });

const step = gpu.createKernel(function (world) {
  let count = 0;
  for (let dy = -1; dy < 2; dy++) {
    for (let dx = -1; dx < 2; dx++) {
      const yy = (this.thread.y + dy + 16) % 16;
      const xx = (this.thread.x + dx + 16) % 16;
      count += world[yy][xx];
    }
  }
  const self = world[this.thread.y][this.thread.x];
  count -= self;
  // TODO: B3/S23 — you wrote this rule last task. Own it.
  return self;
}, { output: [16, 16] });

// world starts as the R-pentomino: five cells, endless trouble.
// TODO: run 6 generations. Each time around: current = await step(current),
// count the live cells in plain JS, then log exactly:
//   console.log('gen ' + g + ': ' + alive + ' alive');
let current = world;
```

---

Interactive version: https://gpu.rocks/learn/cellular-automata-407c2c34/3

[Previous task](https://gpu.rocks/learn/cellular-automata-407c2c34/2.md) · [Next task](https://gpu.rocks/learn/cellular-automata-407c2c34/4.md)
