Self-Playing Flappy Bird

Flappy Bird Screen View

The following demo self-plays a version of Flappy Bird created by Nebez Briefkani.

The modified code is a basic path finding algorithm which runs against the game. After modifying Flappy Bird I learned a lot about what it takes to implement game changes to include Artificial Intelligence. Inserting engine code that integrates with AI was challenging enough but even more difficult was trying to make an agent that played the game without losing. And it took a lot of testing. It works best with Firefox and Chrome.

The game cannot play indefinitely, and the highest score produced was 1398. Some other high scores were 1237 and 1066 out of thousands of attempts.

Try the demo. For best results let it run upwards of an hour or more. I selected a range of parameters which perform the best path finding for the sake of a reasonable run-time without the risk of becoming redundant and boring. However the parameters can be configured over any range. The agent identifies parameters with the best performance and stores them for future use. Once the range is finished the agent will run repeatedly with the stored parameters attempting to achieve increasingly higher scores. >>   Self-Playing Flappy Bird Demo

Floppy Bird Game

The game source is implemented in HTML5/JavaScript by Nebez Briefkani. To download Nebez's source code go here: Floppy Bird Source Code

To play the actual game go here: Play Floppy Bird

Project Files (Modified only)


For display purposes the following highlighted lines were added to the original HTML.

Displays the "TEST Parameters" high and low, "BEST Parameters" high and low, and "HIGH SCORE"

Flappy Bird Parameters

      <div id="gamecontainer">
         <div id="gamescreen">
            <div id="sky" class="animated">
               <div id="flyarea">
               <p id="testparam"></p>  
               <p id="finalparam"></p>  
               <p id="score"></p>  


Modifications to the original Source

The following modifications were added to the original game code to implement the path finding algorithm.

NOTE: None of the orignal bird flight physics were touched, nor the landscape (pipe) dimensions.

The agent calculates the gap space of upcoming pipes to successfully fly the bird between them and find a continuous path without crashing.

Variables that will be explained in detail further down.

var TOP_MIN = 38;  //minimum of the upper range
var BOTTOM_MIN = 1;  //minimum of bottom range  
var TOP_MAX = 50;    //maximum of bottom range 
var BOTTOM_MAX = 25;   //maximum of upper range
var pipetoptest = TOP_MIN;   
var pipebottomtest = BOTTOM_MIN;  
var pipehigh = 0;
var pipelow = 0;
var toploopflag = false;  //used as a marker to iterate thru the ranges within the game loop
var currscore = 0;

In the original code debug mode can be used which draws border boxes around the bird and pipe gaps.

if( == "?debug")
      debugmode = true;     

There are several places where the user input is overidden to restart the bird flying after it crashes or upon start of game.

//get the highscore
   var savedscore = getCookie("highscore");
   if(savedscore != "")
      highscore = parseInt(savedscore);
   //start with the splash screen
   screenClick();    //MC: onLoad launches the bird flying
 //fade in the splash
   $("#splash").transition({ opacity: 1 }, 2000, 'ease');
   screenClick();    //MC: launches bird when "click here" is displayed 
//Handle space bar
   //space bar!
   if(e.keyCode == 32)
      if(currentstate == states.ScoreScreen) {
         // $("#replay").click();  //MC commented out to prevent space bar
      } else {
         //screenClick();   //MC commented out to prevent spacebar

//Handle mouse down OR touch start
//if("ontouchstart" in window)
//   $(document).on("touchstart", screenClick); //MC commented out so it will autorun on mobile device
   //$(document).on("mousedown", screenClick);  //MC commented out to prevent mouse clicks

Below is part of the path finding agent. Another component is the flightPath function.

As each pipe gap is approached by the bird, the gap is calculated and the top and bottom pipe measurements are incremented ( pipetopcalc and pipebottomcalc ) to narrow the target zone for the bird to improve path accuracy. This is repeated each time the bird crashes and if a highest score is reached the incremented amounts are stored for future use after the range testing is complete.

The highest score 1398 was produced with pipetoptest = 41 and pipebottomtest = 13

 document.getElementById("testparam").innerHTML =  "TEST Parameters:  High:  " + pipetoptest + "  Low:  " + pipebottomtest;
    document.getElementById("finalparam").innerHTML = "BEST Parameters:  High:  " + pipehigh + "  Low:  " + pipelow;
    if(toploopflag == false){
       var pipetopparam = pipetoptest;
       var pipebottomparam = pipebottomtest;
    } else {
       var pipetopparam = pipehigh;
       var pipebottomparam = pipelow;
    var pipetopcalc = pipetop + pipetopparam;       
    var pipebottomcalc = pipebottom + pipebottomparam;  
   if(boxtop < pipetopcalc && boxbottom < pipebottomcalc) {
         //Bird is on target to the pipe opening -- DO NOTHING
      } else {

The flightPath function mimics a nested iterative loop, which steps through a range of two sets of numbers for pipetoptest and pipebottomtest.

function flightPath()  
document.getElementById("score").innerHTML = "HIGH SCORE:  " + highscore; 
   if(toploopflag == false) {
            if(currscore <= highscore) {
                  pipebottomtest += 1; 
            if(pipebottomtest > BOTTOM_MAX) {  
                  pipetoptest += 1;
                  pipebottomtest = BOTTOM_MIN;  
    } else {
    if(pipetoptest >= TOP_MAX  && pipebottomtest >= BOTTOM_MAX) {  
        toploopflag = true;