Game of Life
Conway's Game of Life, running at up to 60 generations a second on a wrap-around canvas you can paint into and watch evolve.
Conway's Game of Life is four lines of rules that produce endless behavior, and the appeal is almost entirely in watching it move. A lot of versions I tried slowed down past a small grid, or didn't expose the controls that make it worth poking at: pausing mid-pattern, stepping one generation at a time, or dropping in a glider gun to see where it goes.
I wanted one that stayed smooth at a full screen of cells and let me drive it like an instrument. So the simulation runs on a flat typed array with a second buffer it swaps each tick, the canvas redraws every frame, and everything (speed, grid size, patterns, painting) is wired to controls and keyboard shortcuts so you can stay in the loop while it runs.
How it works
- Typed-array grid: the board lives in a flat
Uint8Arraywith a reused scratch buffer for the next generation, so each tick computes into the scratch and swaps rather than allocating, keeping the renderer steady up to 180×108 cells. - Toroidal neighbours: the edges wrap, so a glider that runs off the right side reappears on the left and spaceships glide forever instead of dying at a wall.
- Drive it live: play, pause, step a single generation, clear, and randomize; a speed slider runs 1 to 60 generations per second; click toggles a cell and dragging paints or erases a whole region.
- Pattern library: drop in known shapes like the Glider, Lightweight Spaceship, Pulsar, Pentadecathlon, R-pentomino, and the Gosper Glider Gun without hand-placing every cell.
- Stats overlay: generation count, live cells, measured FPS, and current grid size update as it runs, plus keyboard shortcuts for play/pause, step, randomize, and clear.
Stack
Vite · React · TypeScript · Tailwind, rendering to a raw Canvas. The simulation is plain typed-array logic kept out of React's render path, so the component tree only handles controls while the grid steps and draws on its own loop.