A Flappy Bird clone where a population of birds teaches itself to play through neuroevolution. Each generation gets a little better.
In 2019 I was co-organizing Bomberjam, an internal competition at work where teams would compete to build the best Bomberman bot. Before the event I wanted to actually understand how you could teach an AI to play a game, not just use a library and hope for the best.
Flappy Bird was the perfect test case: simple rules, immediate feedback, and a clear success condition. The project is inspired by Daniel Shiffman's neuroevolution series on The Coding Train. A population of birds all play at the same time. The ones that survive the longest pass their neural network weights to the next generation with small mutations. Over many generations, the population goes from flying straight into the first pipe to clearing everything.
Pure JavaScript with TensorFlow.js for the neural network layer. Each bird has its own small network that reads the game state and decides whether to flap. Between generations, the best performers are selected, their weights are crossed and mutated, and a new population is created. No backpropagation, no training data, just survival pressure over many generations.
How evolutionary algorithms work in practice, how to implement a neural network from the ground up, and how to use TensorFlow.js. The core concept clicked quickly: you don't need labeled training data if you can define a fitness function. Survival time is the fitness function. The rest is selection, crossover, and mutation.